Projekt LLVM rozwija bezpieczną obsługę buforów w języku C++

Twórcy projektu LLVM zaproponowali szereg zmian mających na celu wzmocnienie bezpieczeństwa kluczowych projektów C++ i zapewnienie środków eliminujących błędy spowodowane przekroczeniem buforów. Prace skupiają się na dwóch obszarach: zapewnieniu modelu programistycznego umożliwiającego bezpieczną pracę z buforami oraz pracy nad wzmocnieniem bezpieczeństwa standardowej biblioteki funkcji libc++.

Proponowany model bezpiecznego programowania w C++ polega na używaniu klas dostarczonych przez standardową bibliotekę podczas pracy z buforami zamiast manipulowania gołymi wskaźnikami. Na przykład proponuje się użycie klas std::array, std::vector i std::span, które dodadzą kontrolę w czasie wykonywania pod kątem nadmiernie przydzielonej pamięci.

Aby przeciwdziałać niebezpiecznym praktykom programistycznym w clang, proponuje się wyświetlanie ostrzeżeń kompilatora dla wszystkich operacji arytmetycznych na wskaźnikach, podobnie do wyjściowych ostrzeżeń lintera clang-tidy podczas używania flagi „cppcoreguidelines-pro-bounds-pointer-arytmetyka”, której obsługa będzie pojawiają się w wydaniu LLVM 16. Aby włączyć takie ostrzeżenia, do clang zostanie dodana osobna flaga, domyślnie nieaktywna.

Planowane jest wdrożenie opcjonalnego rozszerzonego trybu ochrony w libc++, który po włączeniu będzie wychwytywał pewne sytuacje w czasie wykonywania, które prowadzą do niezdefiniowanego zachowania. Na przykład w klasach std::span i std::vector dostęp do pamięci poza dopuszczalnym zakresem będzie monitorowany i w przypadku wykrycia nastąpi awaria programu. Twórcy uważają, że dodanie takich zmian sprawi, że libc++ będzie zgodne ze standardami C++, ponieważ wybór sposobu postępowania w przypadkach niezdefiniowanego zachowania leży w gestii twórców bibliotek, którzy mogą, między innymi, potraktować niezdefiniowane zachowanie jako niepowodzenie, wymagając program do zakończenia.

Planuje się, że kontrole środowiska wykonawczego w libc++ zostaną podzielone na kategorie, które można włączyć indywidualnie. Niektóre z proponowanych kontroli, które nie prowadzą do złożoności operacji lub zmian w ABI, są już zaimplementowane w trybie awaryjnym libc++.

Dodatkowo planowane jest przygotowanie narzędzi do dostosowania kodu, pozwalających na zamianę zmiennych z gołymi wskaźnikami na kontenery oraz wykorzystanie alternatywnych procedur obsługi w sytuacjach, gdy kontener nie może bezpośrednio zastąpić wskaźnika (np. konstrukcja „if(array_pointer)” może zostać przekonwertowane na „if(span.data) ()”). Korekty można stosować nie tylko do zmiennych lokalnych, ale także do parametrów typów wskaźników.

Źródło: opennet.ru

Dodaj komentarz