Sanityzacja przepełnienia liczby całkowitej

Niezamierzone przepełnienia liczb całkowitych mogą powodować uszkodzenie pamięci lub luki w zabezpieczeniach umożliwiające ujawnienie informacji w zmiennych związanych z dostępem do pamięci lub alokacją pamięci. Aby temu zaradzić, dodaliśmy środki odkażające UndefinedBehaviorSanitizer (UBSan) firmy Clang ze znakiem i bez znaku przepełnienia liczb całkowitych, aby wzmocnić strukturę mediów w systemie Android 7.0. W systemie Android 9 rozszerzyliśmy UBSan, aby objąć więcej komponentów i ulepszyć obsługę systemu kompilacji.

Ma to na celu dodanie kontroli wokół operacji / instrukcji arytmetycznych - które mogą się przepełnić - w celu bezpiecznego przerwania procesu, jeśli przepełnienie wystąpi. Te środki dezynfekujące mogą złagodzić całą klasę uszkodzeń pamięci i luk w zabezpieczeniach umożliwiających ujawnienie informacji, których główną przyczyną jest przepełnienie liczb całkowitych, takie jak oryginalna luka Stagefright.

Przykłady i źródło

Integer Overflow Sanitization (IntSan) jest dostarczany przez kompilator i dodaje instrumentację do pliku binarnego podczas kompilacji, aby wykryć przepełnienia arytmetyczne. Jest domyślnie włączony w różnych komponentach platformy, na przykład /platform/external/libnl/Android.bp .

Realizacja

IntSan używa środków odkażających UBSan z przepełnieniem liczb całkowitych ze znakiem i bez znaku. To ograniczenie jest włączone na poziomie modułu. Pomaga zapewnić bezpieczeństwo krytycznym składnikom Androida i nie należy ich wyłączać.

Zdecydowanie zachęcamy do włączenia funkcji Sanityzacja przepełnienia liczby całkowitej dla dodatkowych komponentów. Idealnymi kandydatami są uprzywilejowany kod natywny lub kod natywny, który analizuje niezaufane dane wejściowe użytkownika. Istnieje niewielki narzut wydajności związany ze środkiem dezynfekującym, który zależy od użycia kodu i częstości wykonywania operacji arytmetycznych. Spodziewaj się niewielkiego procentu kosztów ogólnych i sprawdź, czy problemem jest wydajność.

Obsługa IntSan w plikach makefile

Aby włączyć IntSan w pliku makefile, dodaj:

LOCAL_SANITIZE := integer_overflow
# Optional features
LOCAL_SANITIZE_DIAG := integer_overflow
LOCAL_SANITIZE_BLACKLIST := modulename_blacklist.txt
  • LOCAL_SANITIZE pobiera listę środków dezynfekujących oddzielonych przecinkami, przy czym integer_overflow to wstępnie spakowany zestaw opcji dla poszczególnych elementów oczyszczających z przepełnieniem liczb całkowitych ze znakiem i bez znaku z domyślną czarną listą .
  • LOCAL_SANITIZE_DIAG włącza tryb diagnostyczny dla środków odkażających. Używaj trybu diagnostycznego tylko podczas testowania, ponieważ nie spowoduje to przerwania w przypadku przepełnienia, co całkowicie neguje zalety zabezpieczeń wynikające z ograniczenia. Aby uzyskać dodatkowe informacje, zobacz Rozwiązywanie problemów .
  • LOCAL_SANITIZE_BLACKLIST umożliwia określenie pliku czarnej listy, aby zapobiec oczyszczaniu funkcji i plików źródłowych. Aby uzyskać dodatkowe informacje, zobacz Rozwiązywanie problemów .

Jeśli chcesz uzyskać bardziej szczegółową kontrolę, włącz poszczególne środki odkażające, używając jednej lub obu flag:

LOCAL_SANITIZE := signed-integer-overflow, unsigned-integer-overflow
LOCAL_SANITIZE_DIAG := signed-integer-overflow, unsigned-integer-overflow

Obsługa IntSan w plikach schematów

Aby włączyć /platform/external/libnl/Android.bp przepełnienia liczb całkowitych w pliku planu, takim jak /platform/external/libnl/Android.bp , dodaj:

   sanitize: {
      integer_overflow: true,
      diag: {
          integer_overflow: true,
      },
      blacklist: "modulename_blacklist.txt",
   },

Podobnie jak w przypadku plików make, właściwość integer_overflow jest wstępnie spakowanym zestawem opcji dla poszczególnych elementów czyszczących przepełnienia liczb całkowitych ze znakiem i bez znaku z domyślną czarną listą .

diag zestaw właściwości włącza tryb diagnostyczny dla odkażających. Używaj trybu diagnostycznego tylko podczas testowania. Tryb diagnostyczny nie przerywa działania w przypadku przepełnienia, co całkowicie neguje korzyści w zakresie bezpieczeństwa wynikające ze złagodzenia skutków w kompilacjach użytkowników. Aby uzyskać dodatkowe informacje, zobacz Rozwiązywanie problemów .

Właściwość blacklist umożliwia określenie pliku czarnej listy, który umożliwia programistom zapobieganie oczyszczaniu funkcji i plików źródłowych. Aby uzyskać dodatkowe informacje, zobacz Rozwiązywanie problemów .

Aby włączyć poszczególne środki odkażające, użyj:

   sanitize: {
      misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow"],
      diag: {
          misc_undefined: ["signed-integer-overflow",
                           "unsigned-integer-overflow",],
      },
      blacklist: "modulename_blacklist.txt",
   },

Rozwiązywanie problemów

Jeśli włączasz oczyszczanie przepełnienia liczb całkowitych w nowych komponentach lub polegasz na bibliotekach platform, które miały oczyszczanie z przepełnienia liczb całkowitych, możesz napotkać kilka problemów z łagodnymi przepełnieniami całkowitymi powodującymi przerwania. Powinieneś przetestować komponenty z włączoną dezynfekcją, aby upewnić się, że mogą pojawić się łagodne przepełnienia.

Aby znaleźć przerwania spowodowane oczyszczaniem w kompilacjach użytkowników, wyszukaj awarie SIGABRT z komunikatami Abort wskazującymi na przepełnienie przechwycone przez UBSan, takie jak:

pid: ###, tid: ###, name: Binder:###  >>> /system/bin/surfaceflinger <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'ubsan: sub-overflow'

Ślad stosu powinien zawierać funkcję powodującą przerwanie, jednak przepełnienia występujące w funkcjach wbudowanych mogą nie być widoczne w śladzie stosu.

Aby łatwiej określić główną przyczynę, włącz diagnostykę w bibliotece wyzwalającą przerwanie i spróbuj odtworzyć błąd. Po włączeniu diagnostyki proces nie zostanie przerwany, a zamiast tego będzie kontynuowany. Brak przerywania pomaga zmaksymalizować liczbę niegroźnych przepełnień w określonej ścieżce wykonywania bez konieczności ponownej kompilacji po naprawieniu każdego błędu. Diagnostyka generuje komunikat o błędzie, który zawiera numer linii i plik źródłowy powodujący przerwanie:

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:2188:32: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')

Po zlokalizowaniu problematycznej operacji arytmetycznej upewnij się, że przepełnienie jest łagodne i zamierzone (np. Nie ma wpływu na bezpieczeństwo). Możesz rozwiązać problem przerwania odkażania przez:

  • Refaktoryzacja kodu w celu uniknięcia przepełnienia ( przykład )
  • Przepełnienie jawnie przez funkcje Clang __builtin _ * _ overflow ( przykład )
  • Wyłączanie oczyszczania w funkcji przez określenie atrybutu no_sanitize ( przykład )
  • Wyłączanie oczyszczania funkcji lub pliku źródłowego za pomocą pliku czarnej listy ( przykład )

Powinieneś użyć możliwie najbardziej ziarnistego rozwiązania. Na przykład duża funkcja z wieloma operacjami arytmetycznymi i pojedynczą operacją przepełnienia powinna mieć refaktoryzację pojedynczej operacji, a nie całej funkcji na czarnej liście.

Typowe wzorce, które mogą powodować łagodne przepełnienia, obejmują:

  • Niejawne rzuty, w których występuje przepełnienie bez znaku przed rzutowaniem na typ ze znakiem ( przykład )
  • Usunięcia listy połączonej, które zmniejszają indeks pętli po usunięciu ( przykład )
  • Przypisanie typu bez znaku do -1 zamiast określania rzeczywistej wartości maksymalnej ( przykład )
  • Pętle, które zmniejszają liczbę całkowitą bez znaku w warunku ( przykład , przykład )

Zaleca się, aby programiści upewnili się, że w przypadkach, w których środek dezynfekujący wykryje przepełnienie, jest on rzeczywiście niegroźny, bez niezamierzonych skutków ubocznych lub skutków dla bezpieczeństwa, przed wyłączeniem oczyszczania.

Wyłączanie IntSan

Możesz wyłączyć IntSan za pomocą czarnych list lub atrybutów funkcji. Wyłączaj oszczędnie i tylko wtedy, gdy refaktoryzacja kodu jest w inny sposób nieracjonalna lub jeśli występuje problematyczny narzut wydajności.

Więcej informacji na temat wyłączania IntSan za pomocą atrybutów funkcji i formatowania plików czarnej listy można znaleźć w udostępnionej wcześniej dokumentacji Clang. Czarna lista powinna obejmować konkretny środek odkażający, używając nazw sekcji określających docelowy środek odkażający, aby uniknąć wpływu na inne środki odkażające.

Uprawomocnienie

Obecnie nie ma testu CTS specjalnie dla Sanityzacji przepełnienia liczb całkowitych. Zamiast tego upewnij się, że testy CTS przechodzą z włączonym IntSan lub bez niego, aby sprawdzić, czy nie ma on wpływu na urządzenie.