Чи є в Java переповнення буфера?


96

Чи є в Java переповнення буфера? Якщо так, чи можете ви дати мені сценарії?


2
Відомо, що деякі функції бібліотеки (реалізовані у власному коді) мають помилки. Особливо в області Java 5 відомо багато експлойтів у 2D, звуковому або кольоровому профілях.
еккес

Відповіді:


108

Оскільки рядки Java засновані на масивах char, а Java автоматично перевіряє межі масивів, переповнення буфера можливе лише в незвичних сценаріях:

  1. Якщо ви викликаєте власний код через JNI
  2. У самому JVM (зазвичай пишеться на C ++)
  3. Інтерпретатор або JIT-компілятор не працює належним чином (перевірка граничних значень байт-коду Java)

24

Керовані мови, такі як Java та C #, не мають цих проблем, але конкретні віртуальні машини (JVM / CLR / тощо), які насправді запускають код, можуть.


5
C # в небезпечному контексті може мати переповнення буфера. Java як мова цілком забороняє це (ви повинні змінити мови за допомогою JNI, щоб отримати доступ без вказівника)
ShuggyCoUk

1
Гарна думка. З небезпечним C # ви, очевидно, більше не перебуваєте у затишному середовищі в зручному керованому світі.
Брайан Расмуссен

1
Правильно, і навіть якщо ВИ не пишете небезпечного або виконуєте будь-які взаємодії, ви можете використовувати бібліотеку, яка це робить. Отже, цього слід стежити.
BobbyShaftoe

13

Незважаючи на всі наміри та цілі, ні.

Java має перевірку меж масиву, яка перевірятиме, що дані не можуть бути доступні з області за межами виділеного масиву. Коли хтось намагається отримати доступ до області, яка перевищує розмір масиву, ArrayOutOfBoundsбуде вилучено виняток.

Якщо є переповнення буфера, це, мабуть, відбувається через помилку у віртуальній машині Java, і, наскільки мені відомо, це не передбачувана поведінка, яка записана у специфікаціях мови Java, а також у специфікаціях віртуальної машини Java.


10

Так і ні. Ні, оскільки ви не можете насправді створити помилково відкрити себе вразливість до переповнення буфера, оскільки це модель керованої пам'яті. Однак у JVM та JDK можуть бути вразливості до переповнення буфера. Перегляньте цей довідковий документ щодо Secunia

http://secunia.com/advisories/25295

Або перегляньте ці старі рекомендації щодо кількох попередніх уразливостей JDK та JRE:

  • Уразливості переповнення цілого і буфера в середовищі виконання Java (JRE) "unpack200" Утиліта розпакування JAR може призвести до ескалації привілеїв https://download.oracle.com/sunalerts/1020225.1.html

    Уразливості переповнення цілого і буфера в середовищі виконання Java (JRE) із розпаковуванням аплетів та додатків Java Web Start, що використовують утиліту розпакування JAR "unpack200", можуть дозволити ненадійному аплету або програмі посилювати привілеї. Наприклад, ненадійний аплет може надати собі дозволи на читання та запис локальних файлів або виконувати локальні програми, доступні користувачеві, який запускає ненадійний аплет.

    Sun висловлює подяку "regenrecht", що працює з iDefense VCP ( http://labs.idefense.com/vcp/ ) та Крісом Евансом з Google за те, що вони звернули нашу увагу на нашу увагу.

  • У Sun Java Development Kit (JDK) та Java Runtime Environment (JRE) виявлено кілька вразливих місць. https://security.gentoo.org/glsa/200705-23

    Команда безпеки Fujitsu повідомила про невизначену вразливість, пов’язану з „неправильним використанням системних класів”. Крім того, Кріс Еванс із команди безпеки Google повідомив про переповнення цілим числом, що призвело до переповнення буфера в синтаксичному аналізаторі ICC, що використовується з файлами JPG або BMP, і неправильному виклику open () до / dev / tty під час обробки певних файлів BMP.


9

Переповнення буфера в строгому сенсі перезапису стека або купи вимагатиме або:

  1. Помилка у фреймворку (вони існували в минулому і цілком можуть знову)
  2. Використання JNI (по суті більше не використовує керований код)

Переповнення буфера в тому сенсі, що у вас є код, який використовує буфер, і ваш код відповідає за його правильний аналіз, але не зробити цього можливо. Наприклад, ви можете написати синтаксичний аналізатор XML, і хтось може надати вам неправильний (або правомірний, але незвичний) запит, який завдяки дизайну вашого синтаксичного аналізатора замінює раніше перевірені дані деяким корисним навантаженням, що може спричинити погану поведінку вашого додатка.

Ця остання форма менш вірогідна, але погано написана функція очищення рядків sql широко розповсюджена, яка мала таку проблему, як така, що це може бути запрошувальною метою.


4

Віртуальні машини Java (і .Net) ловлять код, який намагається писати поза зарезервованою пам'яттю. Програми, які не справляються з цим правильно, все одно можуть спричинити проблеми із безпекою. Якщо зловмисні користувачі можуть ініціювати винятки, вводячи невірний ввід, вони можуть, наприклад, здійснити атаки відмови в обслуговуванні.


3

Як уже зазначалося, Java як мова має обмеження для перевірки всього доступу до пам'яті, і якщо тут є помилка, винна JVM, а не програма. Однак на що слід звернути увагу, що є подібним аргументом до витоків пам'яті в Java; хоча розбити стек неможливо, вилучення ArrayOutOfBoundsException в неправильному місці, яке обробляється неправильно, все одно може закінчити псувати вашу систему.


3

Ви могли б спричинити переповнення буфера в програмі Java, якщо ви використовували механізм Java Native Interace (JNI) для виклику зовнішнього коду, і зовнішній код мав проблему, яку можна було використати. Це досить рідко, оскільки більшість програм уникають використання JNI, де це можливо.


3

Метод може записати у допустимі записи масиву, який він не мав на меті, як правило, через ціле переповнення.

Наприклад, для перевірки меж недостатньо наступного:

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

IIRC, StringBufferколись мав таку помилку, але з цим не можна було зробити нічого цікавого.


Що є достатнім для перевірки кордонів?
Broam

1
@Broam: 0 <= off && 0 <= len && off <= buff.length-lenЯ думаю. Не цитуй мене. Це виглядає однаково, але можливого переповнення немає (в оригіналі off + len може стати негативним і, отже, очевидно меншим, ніж довжина масиву). Переконайтеся, що жоден програміст з технічного обслуговування ніколи не «прибирає» його в очевидну форму. Я вважаю переповнення цілих чисел дуже заплутаним. Доведеться трохи подумати над цим, а потім виникає настирлива підозра, що я неправильно зрозумів. Але, звичайно, повинен бути інший рецензент та оригінальний програміст - разом, звичайно, жодна помилка не може пройти! (не)
Том Хоутін - таклін

Мені довелося трохи придивитися до цього, але ти маєш рацію. off + len може переповнюватись і обгортати ... в C. На Java , якщо я не помиляюся - ви отримаєте виняток із переповнення до того, що сталося, правда?
Broam

1
Ні. Ціла арифметика мовчки обертається навколо. У C # є "режим", коли виключення передається при переповненні, але я не думаю, що він використовується багато (якщо ви хочете його використовувати, ви, мабуть, все-таки подумаєте робити правильні речі).
Tom Hawtin - таклін

1

Однією з ключових особливостей JAVA є безпека. Програми, написані мовами, що інтерпретуються, не схильні до використання переповнення буфера, але ви завжди можете викликати переповнення буфера в самому інтерпретаторі. Хоча це буде важко. Подібним чином Python також є інтерпретованою мовою і захищений від переповнення буфера.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.