Przekroczenie zakresu liczb całkowitych
| Ten artykuł należy dopracować zgodnie z zaleceniami edycyjnymi: merytorycznie; to nie błąd per se, tylko rodzaj zachowania; wymieszane wyrażenia dot. procesora (carry flag), C i abstrakcyjne; zwykłe błędy (wg standardu "przekręcenie się" liczby typu signed to undefined behavior). Po wyeliminowaniu niedoskonałości prosimy usunąć szablon {{Dopracować}} z kodu tego artykułu. |
Przekroczenie zakresu liczb całkowitych (ang. integer overflow) – błąd programistyczny, spowodowany nieprawidłowym oszacowaniem zakresu wartości, które może przyjąć zmienna w trakcie pracy programu. Możliwą konsekwencją błędu tego typu jest nadpisanie pamięci poprzedzającej bufor lub przepełnienie bufora, co w konsekwencji może prowadzić do przejęcia kontroli nad podatną aplikacją przez osobę trzecią.
Szczegóły techniczne [edytuj]
Użyta architektura sprzętowa-programowa determinuje rozmiar danych typu całkowitego. Najczęściej mają one pojemność 8, 16, 32, 64 lub 128 bitów; parametr ten wynika z charakterystyki rejestrów procesora oraz konwencji obowiązujących w danym języku programowania. Dodatkowo, ustalony jest sposób reprezentacji liczb dodatnich i ujemnych, najczęściej z wykorzystaniem kodu uzupełnień do dwóch.
Rezultat operacji arytmetycznej może wykroczyć poza dostępny zakres użytego w obliczeniach typu danych. W takiej sytuacji, zwykle dochodzi do utraty najstarszych bitów wyniku (efekt slangowo określany jako przekręcenie się licznika), i ustawienia odpowiedniej flagi (carry flag), która informuje programistę o nieprawidłowości wyniku.
Niektóre języki nie przewidują automatycznego sprawdzania wspomnianej flagi: w standardzie ISO C99, wynik operacji, dla której zachodzi błąd przekroczenia zakresu liczb całkowitych, jest po prostu niezdefiniowany (a w praktyce, zgodny z wyżej opisanym zachowaniem). W takiej sytuacji może dojść do kilku nieprzewidzianych przez programistę sytuacji:
- Jeśli zmienna używana jest jako licznik, program może w efekcie niedoszacować rozmiar danych, które pobrano do pamięci od użytkownika (na przykład: pobrano 257 bajtów, ale licznik "przekręcił się" i wskazuje tylko 1) – co prowadzić może później do nadpisania bufora przy kopiowaniu danych,
- Jeśli zmienna ze znakiem używana jest jako indeks tablicy, może dojść do zmiany znaku zmiennej, i odwołania się do pamięci znajdującej się przed tablicą (ujemny indeks) – co umożliwia często nadpisanie struktur kontrolnych programu.
Co ciekawe, nawet jeśli sama zmienna licznikowa jest należycie chroniona przed przekroczeniem dopuszczalnego zakresu wartości, w pewnych sytuacjach – między innymi w funkcji calloc() – dochodzi do ukrytego mnożenia parametru przez rozmiar struktury, która powinna zostać zaalokowana (na przykład, gdy programista chce zaalokować pamięć na 1000 elementów o rozmiarze 16 bajtów, dojdzie do przemnożenia 1000 * 16). Taka sytuacja może prowadzić do subtelnych i trudnych do wykrycia błędów tego typu.
Implikacje dla bezpieczeństwa aplikacji [edytuj]
Błędy przekroczenia zakresu liczb całkowitych prowadzą często do zagrożenia bezpieczeństwa aplikacji. Dzieje się tak w środowisku, w którym kontrolowany przez osobę trzecią błąd przekroczenie zakresu liczb całkowitych nie powoduje sytuacji wyjątkowej, lub w którym ta sytuacja nie jest obsłużona prawidłowo.