Luki w podsystemie eBPF umożliwiające wykonanie kodu na poziomie jądra Linuksa

W podsystemie eBPF zidentyfikowano dwie nowe luki, które umożliwiają uruchamianie procedur obsługi wewnątrz jądra Linuksa na specjalnej maszynie wirtualnej z JIT. Obie luki umożliwiają wykonanie kodu z uprawnieniami jądra, poza izolowaną maszyną wirtualną eBPF. Informację o problemach opublikował zespół Zero Day Initiative, organizujący konkurs Pwn2Own, podczas którego w tym roku wykazano trzy ataki na Ubuntu Linux, w których wykorzystano nieznane wcześniej luki (nie zgłoszono, czy luki w eBPF mają związek z tymi atakami). .

  • CVE-2021-3490 — Luka jest spowodowana brakiem 32-bitowego sprawdzania przekroczeń zakresu podczas wykonywania bitowych operacji AND, OR i XOR w eBPF ALU32. Osoba atakująca może wykorzystać ten błąd do odczytu i zapisu danych poza granicami przydzielonego bufora. Problem z operacjami XOR pojawia się począwszy od wersji jądra 5.7-rc1, a AND i OR - począwszy od wersji 5.10-rc1.
  • CVE-2021-3489 - Luka jest spowodowana błędem w implementacji bufora pierścieniowego i wynika z faktu, że funkcja bpf_ringbuf_reserve nie sprawdziła możliwości, że rozmiar przydzielonego obszaru pamięci może być mniejszy niż rozmiar rzeczywisty z ringbufa. Problem pojawia się od wersji 5.8-rc1.

Stan łatania luk w dystrybucjach można śledzić na stronach: Ubuntu, Debian, RHEL, Fedora, SUSE, Arch). Poprawki są również dostępne w postaci łatek (CVE-2021-3489, CVE-2021-3490). Możliwość wykorzystania problemu zależy od tego, czy wywołanie systemowe eBPF jest dostępne dla użytkownika. Na przykład w domyślnej konfiguracji w RHEL wykorzystanie luki wymaga posiadania przez użytkownika uprawnień CAP_SYS_ADMIN.

Osobno możemy zauważyć kolejną lukę w jądrze Linuksa - CVE-2021-32606, która pozwala użytkownikowi lokalnemu podnieść swoje uprawnienia do poziomu root. Problem jest widoczny od jądra Linuksa 5.11 i jest spowodowany wyścigiem w implementacji protokołu CAN ISOTP, który umożliwia zmianę parametrów wiązania gniazda ze względu na brak ustawienia odpowiednich blokad w funkcji isotp_setsockopt() podczas przetwarzania flagi CAN_ISOTP_SF_BROADCAST.

Po zamknięciu gniazda ISOTP pozostaje w mocy powiązanie z gniazdem odbiorcy, który może w dalszym ciągu korzystać ze struktur skojarzonych z gniazdem po zwolnieniu skojarzonej z nimi pamięci (use-after-free ze względu na wywołanie struktury isotp_sock który został już zwolniony po wywołaniu isotp_rcv()). Poprzez manipulację danymi możesz zastąpić wskaźnik do funkcji sk_error_report() i wykonać kod na poziomie jądra.

Źródło: opennet.ru

Dodaj komentarz