Czy Java ma przepełnienia bufora?


96

Czy Java ma przepełnienia bufora? Jeśli tak, czy możesz podać mi scenariusze?


2
Wiadomo, że niektóre funkcje biblioteczne (zaimplementowane w kodzie natywnym) zawierają błędy. Zwłaszcza w obszarze Java 5 znanych jest wiele exploitów w profilach 2D, dźwiękowych lub kolorystycznych.
eckes,

Odpowiedzi:


108

Ponieważ ciągi znaków w języku Java są oparte na tablicach znaków, a język Java automatycznie sprawdza granice tablic, przepełnienia buforu są możliwe tylko w nietypowych scenariuszach:

  1. Jeśli wywołasz kod natywny za pośrednictwem JNI
  2. W samej JVM (zwykle napisane w C ++)
  3. Interpreter lub kompilator JIT nie działa poprawnie (sprawdzanie ograniczeń na podstawie kodu bajtowego Java)

24

Języki zarządzane, takie jak Java i C #, nie mają tych problemów, ale konkretne maszyny wirtualne (JVM / CLR / itp.), Które faktycznie uruchamiają kod, mogą.


5
C # w niebezpiecznym kontekście może mieć przepełnienia buforu. Java jako język całkowicie tego zabrania (musisz zmienić język przez JNI, aby uzyskać niezmieniony dostęp do wskaźnika)
ShuggyCoUk

1
Słuszna uwaga. Z niebezpiecznym C # oczywiście nie jesteś już piaskownicą w wygodnie zarządzanym świecie.
Brian Rasmussen

1
Zgadza się, a nawet jeśli TY nie piszesz żadnych niebezpiecznych plików ani nie wykonujesz żadnej współpracy, możesz korzystać z biblioteki, która to robi. Więc to jest coś, na co trzeba uważać.
BobbyShaftoe

13

Dla wszystkich zamiarów i celów, nie.

Java ma funkcję sprawdzania granic tablic, która sprawdza, czy nie można uzyskać dostępu do danych z obszaru spoza przydzielonej tablicy. Gdy ktoś próbuje uzyskać dostęp do obszaru, który jest poza rozmiarem tablicy, plikArrayOutOfBounds zostanie zgłoszony wyjątek.

Jeśli występuje przepełnienie buforu, jest to prawdopodobnie spowodowane błędem w wirtualnej maszynie języka Java i, o ile mi wiadomo, nie jest to zamierzone zachowanie opisane w specyfikacjach języka Java ani w specyfikacjach wirtualnej maszyny języka Java.


10

Tak i nie. Nie, ponieważ tak naprawdę nie można tworzyć błędnie, otworzyć się na lukę przepełnienia bufora, ponieważ jest to model pamięci zarządzanej. Jednak w JVM i JDK mogą występować luki w zabezpieczeniach przepełnienia buforu. Zobacz ten poradnik Secunia:

http://secunia.com/advisories/25295

Lub zobacz te stare porady dotyczące kilku poprzednich luk w zabezpieczeniach JDK i JRE:

  • Luki w zabezpieczeniach związane z przepełnieniem liczb całkowitych i buforu w środowisku wykonawczym Java (JRE) „unpack200” narzędzia do rozpakowywania plików JAR mogą prowadzić do eskalacji uprawnień https://download.oracle.com/sunalerts/1020225.1.html

    Luki w zabezpieczeniach związane z przepełnieniem liczb całkowitych i bufora w środowisku Java Runtime Environment (JRE) przy rozpakowywaniu apletów i aplikacji Java Web Start przy użyciu narzędzia do rozpakowywania JAR „unpack200” mogą pozwolić niezaufanemu apletowi lub aplikacji na zwiększenie uprawnień. Na przykład niezaufany aplet może przyznać sobie uprawnienia do odczytu i zapisu plików lokalnych lub wykonywania lokalnych aplikacji, które są dostępne dla użytkownika uruchamiającego niezaufany aplet.

    Firma Sun dziękuje „regenrecht” za współpracę z iDefense VCP ( http://labs.idefense.com/vcp/ ) i Chrisowi Evansowi z Google za zwrócenie naszej uwagi na te kwestie.

  • Zidentyfikowano wiele luk w zabezpieczeniach Sun Java Development Kit (JDK) i Java Runtime Environment (JRE). https://security.gentoo.org/glsa/200705-23

    Zespół ds. Bezpieczeństwa firmy Fujitsu zgłosił nieokreśloną lukę w zabezpieczeniach polegającą na „nieprawidłowym użyciu klas systemowych”. Ponadto Chris Evans z zespołu Google Security Team zgłosił przepełnienie całkowitoliczbowe powodujące przepełnienie buforu w parserze ICC używanym z plikami JPG lub BMP oraz nieprawidłowe wywołanie open () do / dev / tty podczas przetwarzania niektórych plików BMP.


9

Przepełnienie buforu w ścisłym znaczeniu nadpisania samego stosu lub samej sterty wymagałoby:

  1. Błąd we frameworku (te istniały w przeszłości i mogą znowu)
  2. Użycie JNI (zasadniczo nie używa już kodu zarządzanego)

Przepełnienie buforu w tym sensie, że kod używa bufora, a kod jest odpowiedzialny za jego poprawną analizę, ale nie jest to możliwe. Na przykład możesz napisać parser XML i ktoś mógłby dostarczyć źle sformułowane (lub uzasadnione, ale rzadkie) żądanie, które z powodu projektu twojego parsera nadpisuje wcześniej sprawdzone dane jakimś ładunkiem, który spowodowałby złe zachowanie aplikacji.

Ta ostatnia forma jest mniej prawdopodobna, ale źle napisana funkcja czyszczenia łańcucha sql, szeroko rozpowszechniona, która miała taki problem, byłaby zachęcającym celem.


4

Maszyny wirtualne Java (i .Net) przechwytują kod, który próbuje pisać poza zarezerwowaną pamięcią. Aplikacje, które nie obsługują tego poprawnie, nadal mogą powodować problemy z bezpieczeństwem. Jeśli złośliwi użytkownicy mogą wywołać wyjątki, wprowadzając nieprawidłowe dane wejściowe, mogą na przykład przeprowadzać ataki typu „odmowa usługi”.


3

Jak już zostało powiedziane, Java jako język ma granice sprawdzania dostępu do całej pamięci, a jeśli wystąpi tutaj błąd, winna jest JVM, a nie program. Jednak należy zauważyć, że jest to argument podobny do wycieków pamięci w Javie; Chociaż nie jest możliwe rozbicie stosu, wyjątek ArrayOutOfBoundsException w niewłaściwym miejscu, który nie jest obsługiwany poprawnie, może nadal zepsuć system.


3

Można sobie wyobrazić przepełnienie bufora w programie Java, jeśli do wywołania kodu zewnętrznego używa się narzędzia Java Native Interace (JNI), a kod zewnętrzny zawiera problem, który można wykorzystać. Jest to dość rzadkie, ponieważ większość aplikacji unika używania JNI tam, gdzie to możliwe.


3

Metoda może zapisywać poprawne wpisy tablicy, których nie zamierzała, zazwyczaj poprzez przepełnienie całkowitoliczbowe.

Na przykład poniższe elementy nie wystarczą, aby sprawdzić granice:

/* !! WRONG !! */ 0 <= off && 0 <= len && off+len <= buff.length /* !! WRONG !! */

IIRC, StringBufferkiedyś miał taki błąd, ale nie można było z nim nic ciekawego zrobić.


Co jest wystarczające, aby sprawdzić granice?
Broam

1
@Broam: 0 <= off && 0 <= len && off <= buff.length-lenMyślę. Nie cytuj mnie. Wygląda tak samo, ale nie ma możliwości przepełnienia (w oryginale off + len może być ujemne, a zatem oczywiście mniejsze niż długość tablicy). Upewnij się, że żaden programista nigdy nie „porządkuje” go w oczywistej formie. Uważam, że przepełnienie liczb całkowitych jest bardzo mylące. Muszę chwilę o tym pomyśleć, a potem pojawia się dokuczliwe podejrzenie, że się mylę. Ale oczywiście powinien być jeszcze jeden recenzent i oryginalny programista - razem oczywiście nie ma możliwości przedostania się błędu! (nie)
Tom Hawtin - tackline

Musiałem trochę się temu przyjrzeć, ale masz rację. off + len mogłoby się przepełnić i zawinąć ... w C. W Javie , chyba że się mylę - przed tym wystąpiłbyś wyjątek przepełnienia, prawda?
Broam

1
Nie. Arytmetyka liczb całkowitych po cichu zawija. C # ma „tryb”, w którym wyjątek jest zgłaszany w przypadku przepełnienia, ale nie sądzę, aby był on często używany (jeśli myślisz o jego użyciu, prawdopodobnie i tak pomyślałbyś o zrobieniu właściwych rzeczy).
Tom Hawtin - tackline

1

Jedną z kluczowych cech JAVA jest bezpieczeństwo. Programy napisane w językach interpretowanych nie są podatne na exploity przepełnienia bufora, ale zawsze możesz spowodować przepełnienie bufora w samym Interpreterze. Chociaż będzie to trudne. Podobnie Python jest również językiem interpretowanym i jest bezpieczny przed przepełnieniem bufora.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.