Az egész szám túlcsordulása a számítógépes aritmetika olyan helyzete, amelyben a művelet eredményeként számított érték nem helyezhető el n bites egész adattípusba. Tegyen különbséget az ábrázolás felső határán keresztül történő túlcsordulás és az alsó határon keresztül ( angol Underflow ).
Példa: két 8 bites változó hozzáadása és az eredmény tárolása egy azonos méretű változóban:
túlcsordulás lép fel.
Ebben az esetben az eredményt nem a várt , hanem a . Érdemes megjegyezni, hogy a számítás itt modulo 2 n , és a modulo aritmetika ciklikus, azaz 255+1=0 (n = 8 esetén). Ezt a túlcsordulási helyzetet a számítógép az Overflow és Carry jelzők regiszterének speciális bitjeinek beállításával javítja (3.4.3.1 Kombinált kötet: 1. kötet [1] ). Assembly nyelven történő programozáskor egy ilyen helyzet közvetlenül megállapítható, például a jelzőregiszter állapotának manuális ellenőrzésével a művelet végrehajtása után (7.3.13.2. Kombinált kötet: 1. kötet [1] ).
Egy regiszter bitmélysége határozza meg a benne ábrázolható adatok körét. Az egész típusok ábrázolási tartományai bináris számítógépekben:
Bitness | 8 bites | 16 bites | 32 bites | 64 bites | |
aláírás nélküli | Hatótávolság | 0..2 8 −1 | 0..2 16 −1 | 0..2 32 −1 | 0..2 64 −1 |
Tartomány (tizedes) | 0..255 | 0..65535 | 0..4294967295 | 0.. 18446744073709551615 | |
ikonszerű | Hatótávolság | -2 7 .. 2 7 −1 | -2 15 .. 2 15 −1 | -2 31 .. 2 31 −1 | -2 63 .. 2 63 −1 |
Tartomány (tizedes) | -128..127 | -32768..32767 | -2147483648.. 2147483647 | -9223372036854775808.. 9223372036854775807 |
Túlcsordulás fordulhat elő a forráskódban a programozó hibája vagy a bemeneti adatok éberségének hiánya miatt [2] .
A túlcsordulási képességet a programozók széles körben használják például kivonatolásra és kriptográfiára, véletlen számok generálására és a típusábrázolás határainak megtalálására [4] . Ugyanakkor például a C és C++ nyelvek szabványa szerint az előjel nélküli számításokat modulo 2 végzi, míg az előjeles túlcsordulás a definiálatlan viselkedés klasszikus példája [5] [6] .
A kód ilyen jellegű helytelensége a következő következményekkel jár [4] :
A szabvány megváltoztatása új túlcsordulási problémákat okozhat. Például az 1<<31 az ANSI C és C++98 szabványokban implementációfüggő volt , míg a C99 és C11 (32 bites egész számok esetén) definiálatlanná vált. [négy]
Ezenkívül egy ilyen hibának egyéb következményei is lehetnek, például puffertúlcsordulás .
Főbb biztonsági vonatkozások [7] :
Klasszikusan a túlcsordulást puffertúlcsorduláson keresztül lehet kihasználni.
img_t * table_ptr ; /*képadatokat tartalmazó struktúra, mindegyik 10 kB*/ int num_imgs ; ... num_imgs = get_num_imgs (); table_ptr = ( img_t * ) malloc ( sizeof ( img_t ) * num_imgs ); ...Ez a példa [7] egyszerre több sebezhetőséget mutat be. Először is, a túl nagy num_imgs hatalmas puffert foglal le, ami a program összes rendszererőforrásának felhasználását vagy összeomlását okozhatja .
Egy másik sebezhetőség az, hogy ha a num_imgs még nagyobb, akkor túlcsordul a malloc argumentum. Ekkor csak egy kis puffer kerül lefoglalásra. Amikor ír rá, puffertúlcsordulás lép fel , aminek a következményei lehetnek: a végrehajtás feletti irányítás elfogása, a támadó kódjának végrehajtása, fontos információkhoz való hozzáférés. [nyolc]
Az ilyen viselkedés elleni védelmet több szinten kell végrehajtani [7] :
A sérülékenységek elkerülésére a 2008-ban a CERT C Secure Coding Standardban közzétett további szabályok a következők: [9] :
A [4] cikkben az egész szám túlcsordulásra szolgáló C és C++ programok tanulmányozásának tárgyaként az egyik legszélesebb körben használt és legismertebb teljesítménymérésre használt SPEC tesztcsomagot tanulmányozzuk részletesen. A leggyakoribb feladatok töredékeiből áll, mint például: számítási matematikai tesztek, fordítás, adatbázisokkal, lemezzel, hálózattal stb.
A SPECCINT2000 elemzés eredményei 12 benchmark közül 8-ban 219 statikus túlcsordulási forrás jelenlétét mutatják, amelyek közül 148 előjel nélküli túlcsordulást, 71 pedig előjeles túlcsordulást ( megint meghatározatlan viselkedés ) használt. Ugyanakkor az előjel nélküli túlcsordulás szintén nem mindig szándékos, és hiba és sebezhetőség forrása lehet (például ugyanazon cikk 2. listája [4] ).
"Időzített bombákra" is tesztelték a SPECCINT2006-ban. Az ő ötlete az, hogy minden meghatározatlan viselkedés helyén egy véletlen számot adjon vissza, és nézze meg, hogy ez milyen következményekkel járhat. Ha a definiálatlan viselkedést a C99 / C ++ 11 szabvány szempontjából értékeljük, akkor 9 benchmarkból akár 6 is megbukik a teszten.
Ez a kódrészlet [4] az IntegerLib csomagból ellenőrzi, hogy az lhs és az rhs összeadható-e túlcsordulás nélkül. És pontosan a 3. sorban fordulhat elő ez a túlcsordulás (lhs + rhs összeadásakor). Ez az UB, mert az lhs és rhs előjeles típusok. Ezenkívül 19 további UB-túlcsordulást találtunk ebben a könyvtárban.
A szerzők emellett 13 túlcsordulásról számoltak be az SQLite-ben, 43-ról a SafeInt-ben, 6-ról a GNU MPC-könyvtárban, 30-ról a PHP-ben, 18-ról a Firefoxban, 71-ről a GCC-ből, 29-ről a PostgreSQL-ből, 5-ről az LLVM-ből és 28-ról a Python-ban. A hibák nagy részét hamarosan kijavították.
Az egész számok túlcsordulásának híres példája a Pac-Man játékban fordul elő , akárcsak a sorozat többi játéka: Ms. Pac-Man , Jr. Pac Man . Ezenkívül ez a hiba a Pac-Man Google Doodle-ben az úgynevezett "Easter Egg" néven jelenik meg. [10] Itt, a 256. szinten egy " halál képernyője " figyelhető meg, és magát a szintet " osztott képernyő szintnek " nevezik. A rajongók szétszedték a forráskódot, hogy a játék módosításával kijavítsák a hibát .
Ugyanez a probléma volt állítólag a Sid Meier's Civilization játékban, és Nuclear Gandhiként ismert [11] . A legenda szerint a játék egy nagyon békés Gandhival egy pontján az ellenségeskedés 0 szintjén túlcsordul , ami nukleáris háborúhoz vezethet Gandhival. Valójában egy ilyen mítosz csak a Civilization V megjelenésével jelent meg, ahol a nukleáris fegyverek létrehozását és használatát szabályozó mesterséges intelligenciájának paramétere a legmagasabb, 12-es, ami nem mond ellent annak, hogy Gandhi egy a játék legbékésebb vezetői közül [12] .
Egy másik példa a SimCity 2000 [13] hibája . A lényeg itt az, hogy a játékos költségvetése nagyon nagy lett, és miután átment 2 31 -en, hirtelen negatív lett. A játék vereséggel végződik.
Ez a hiba a Diablo III -tól származik . Az 1.0.8-as javítás egyik változása miatt a játék gazdasága összeomlott. A tranzakciók maximális összegét 1 millióról 10 millióra emelték, a vételi költség túlcsordult a 32 bites típuson, és a művelet lemondásakor a teljes összeg visszajárt. Vagyis a játékos 2 32 játékvaluta nyereséggel maradt [14]