Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

Безопасность памяти - это состояние защиты от различных программных ошибок и уязвимостей при обращении к памяти , таких как переполнение буфера и висячие указатели . [1] Например, Java считается безопасной для памяти, потому что ее обнаружение ошибок во время выполнения проверяет границы массива и разыменование указателей. [1] В отличие от этого, C и C ++ допускают произвольную арифметику указателей с указателями, реализованными как прямые адреса памяти без возможности проверки границ , [2]и поэтому потенциально небезопасны для памяти . [3]

История [ править ]

Ошибки памяти сначала были рассмотрены в контексте систем управления ресурсами и разделения времени, чтобы избежать таких проблем, как « бомбы вилки» . [4] Разработки были в основном теоретическими до червя Морриса , который использовал переполнение буфера в fingerd . [5] С тех пор область компьютерной безопасности быстро развивалась, увеличиваясь с появлением множества новых атак, таких как атака с возвратом к libc, и методы защиты, такие как неисполняемый стек [6] и рандомизация структуры адресного пространства.. Рандомизация предотвращает большинство атак на переполнение буфера и требует от злоумышленника использования распыления кучи или других зависимых от приложения методов для получения адресов, хотя его внедрение было медленным. [5] Однако развертывание технологии обычно ограничивается рандомизацией библиотек и расположением стека.

Подходы [ править ]

DieHard [7], его редизайн DieHarder, [8] и Allinea Distributed Debugging Tool - это специальные распределители кучи, которые выделяют объекты на их собственной странице случайной виртуальной памяти, позволяя останавливать и отлаживать недопустимые операции чтения и записи и отлаживать их по той инструкции, которая их вызывает. . Защита полагается на аппаратную защиту памяти, поэтому накладные расходы обычно невелики, хотя они могут значительно возрасти, если программа интенсивно использует выделение памяти. [9] Рандомизация обеспечивает только вероятностную защиту от ошибок памяти, но часто может быть легко реализована в существующем программном обеспечении путем повторного связывания двоичного файла.

Инструмент memcheck от Valgrind использует симулятор набора инструкций и запускает скомпилированную программу на виртуальной машине с проверкой памяти, обеспечивая гарантированное обнаружение подмножества ошибок памяти во время выполнения. Однако это обычно замедляет программу в 40 раз [10], и, кроме того, необходимо явно сообщить о пользовательских распределителях памяти. [11] [12]

Имея доступ к исходному коду, существуют библиотеки, которые собирают и отслеживают допустимые значения указателей («метаданные») и проверяют каждый доступ указателя на соответствие метаданным на предмет достоверности, например сборщик мусора Boehm . [13] В общем, безопасность памяти может быть гарантирована с помощью трассировки сборки мусора и вставки проверок времени выполнения при каждом доступе к памяти; у этого подхода есть накладные расходы, но меньше, чем у Valgrind. Все языки со сборкой мусора используют этот подход. [1] Для C и C ++ существует множество инструментов, которые выполняют преобразование кода во время компиляции для проверки безопасности памяти во время выполнения, например CheckPointer [14] и AddressSanitizer.что предполагает средний коэффициент замедления, равный 2. [15]

Другой подход использует статический анализ программы и автоматическое доказательство теорем, чтобы гарантировать, что программа свободна от ошибок памяти. Например, в языке программирования Rust реализована проверка заимствований для обеспечения безопасности памяти. [16] Такие инструменты, как Coverity, предлагают статический анализ памяти для C. [17] Интеллектуальные указатели C ++ являются ограниченной формой этого подхода.

Типы ошибок памяти [ править ]

Может возникнуть много различных типов ошибок памяти: [18] [19]

  • Ошибки доступа : недопустимое чтение / запись указателя
    • Переполнение буфера - записи вне пределов могут привести к повреждению содержимого соседних объектов или внутренних данных (например, бухгалтерской информации для кучи ) илиадресов возврата .
    • Перечитывание буфера - чтение за пределами диапазона может выявить конфиденциальные данные или помочь злоумышленникам обойти рандомизацию разметки адресного пространства .
    • Состояние гонки - одновременное чтение / запись в разделяемую память
    • Ошибка неверной страницы - доступ к указателю за пределами области виртуальной памяти. Разыменование нулевого указателя часто вызывает исключение или завершение программы в большинстве сред, но может вызвать повреждение ядер операционной системыили систем без защиты памяти , или когда использование нулевого указателя связано с большим или отрицательным смещением.
    • Использовать после освобождения - разыменование висячего указателя, в котором хранится адрес удаленного объекта.
  • Неинициализированные переменные - используется переменная, которой не присвоено значение. Он может содержать нежелательное или, в некоторых языках, искаженное значение.
    • Null указатель разыменования - разыменования неверный указатель или указатель на памятькоторая не была выделена
    • Дикие указатели возникают, когда указатель используется до инициализации некоторого известного состояния. Они демонстрируют такое же беспорядочное поведение, что и висячие указатели, хотя с меньшей вероятностью останутся незамеченными.
  • Утечка памяти - когда использование памяти не отслеживается или отслеживается неправильно
    • Исчерпание стека - возникает, когда программе не хватает места в стеке, обычно из-за слишком глубокой рекурсии . Страница охранник обычно останавливает программу, предотвращая повреждение памяти, но функции с большими кадрами стеки могут обойти страницу.
    • Исчерпание кучи - программа пытается выделить больше памяти, чем доступно. В некоторых языках это условие необходимо проверять вручную после каждого распределения.
    • Double free - повторные звонки на free могут преждевременно освободить новый объект по тому же адресу. Если точный адрес не использовался повторно, может произойти другое повреждение, особенно в распределителях, которые используют списки свободных адресов .
    • Invalid free - передача недопустимого адреса в free может повредить кучу .
    • Mismatched free - при использовании нескольких распределителей, попытка освободить память с помощью функции освобождения другого распределителя [20]
    • Нежелательное сглаживание - когда одна и та же область памяти выделяется и изменяется дважды для несвязанных целей.

Ссылки [ править ]

  1. ^ a b c Дхурджати, Динакар; Ковшик, Сумант; Адве, Викрам; Латтнер, Крис (1 января 2003 г.). «Безопасность памяти без проверок во время выполнения или сборки мусора» (PDF) . Материалы конференции ACM SIGPLAN 2003 г. по языку, компилятору и инструментам для встроенных систем . ACM: 69–80. DOI : 10.1145 / 780732.780743 . ISBN 1581136471. Проверено 13 марта 2017 года .
  2. ^ Кениг, Эндрю. «Как C затрудняет проверку границ массива» . Доктора Добба . Проверено 13 марта 2017 года .
  3. ^ АКРИТИДИС, Periklis (июнь 2011). «Практическая безопасность памяти для C» (PDF) . Технический отчет - Кембриджский университет. Компьютерная лаборатория . Кембриджский университет, компьютерная лаборатория. ISSN 1476-2986 . UCAM-CL-TR-798 . Проверено 13 марта 2017 года .  
  4. ^ Андерсон, Джеймс П. «Исследование планирования компьютерной безопасности» (PDF) . 2 . Центр электронных систем . ESD-TR-73-51. Цитировать журнал требует |journal=( помощь )
  5. ^ а б ван дер Вин, Виктор; дутт-Шарма, Нитиш; Кавалларо, Лоренцо; Бос, Герберт (2012). «Ошибки памяти: прошлое, настоящее и будущее» (PDF) . Конспект лекций по информатике . 7462 (RAID 2012): 86–106. DOI : 10.1007 / 978-3-642-33338-5_5 . ISBN  978-3-642-33337-8. Проверено 13 марта 2017 года .
  6. ^ Войтчук, Рафаль. «Победа над неисполняемым патчем стека Solar Designer's» . insecure.org . Проверено 13 марта 2017 года .
  7. ^ Бергер, Эмери Д .; Цорн, Бенджамин Г. (1 января 2006 г.). «DieHard: вероятностная безопасность памяти для небезопасных языков» (PDF) . Труды 27-й конференции ACM SIGPLAN по проектированию и реализации языков программирования . ACM: 158–168. DOI : 10.1145 / 1133981.1134000 . Проверено 14 марта 2017 года .
  8. ^ Новарк, Джин; Бергер, Эмери Д. (1 января 2010 г.). «DieHarder: защита кучи» (PDF) . Труды 17-й конференции ACM по компьютерной и коммуникационной безопасности . ACM: 573–584. DOI : 10.1145 / 1866307.1866371 . Проверено 14 марта 2017 года .
  9. ^ «Отладка памяти в Allinea DDT» . Архивировано из оригинала на 2015-02-03.
  10. ^ Джилленхол, Джон. «Использование инструмента Valgrind Memcheck для поиска ошибок и утечек памяти» . computing.llnl.gov . Архивировано из оригинального 7 -го ноября 2018 года . Проверено 13 марта 2017 года .
  11. ^ "Memcheck: детектор ошибок памяти" . По эксплуатации Valgrind . valgrind.org . Проверено 13 марта 2017 года .
  12. ^ Крейнин, Йосси. «Почему сложно настраиваемые распределители / пулы» . Правильная фиксация . Проверено 13 марта 2017 года .
  13. ^ «Использование сборщика мусора в качестве детектора утечек» . www.hboehm.info . Проверено 14 марта 2017 года .
  14. ^ «Семантические проекты: CheckPointer по сравнению с другими инструментами проверки безопасности» . www.semanticdesigns.com . Semantic Designs, Inc.
  15. ^ "AddressSanitizerPerformanceNumbers" .
  16. ^ «Ссылки» . Рустономикон . Rust.org . Проверено 13 марта 2017 года .
  17. ^ Бесси, Ал; Энглер, Доусон; Блок, Кен; Шельф, Бен; Чоу, Энди; Фултон, Брайан; Халлем, Сет; Анри-Гро, Шарль; Камский, Ася; Макпик, Скотт (1 февраля 2010 г.). «Через несколько миллиардов строк кода» . Коммуникации ACM . 53 (2): 66–75. DOI : 10.1145 / 1646353.1646374 . Проверено 14 марта 2017 года .
  18. ^ Гв, Нэвин. «Как избежать, найти (и исправить) ошибки памяти в вашем коде C / C ++» . Cprogramming.com . Проверено 13 марта 2017 года .
  19. ^ «CWE-633: Слабости, влияющие на память» . Подсчет слабых сторон сообщества . МИТРА . Проверено 13 марта 2017 года .
  20. ^ «CWE-762: Несоответствующие процедуры управления памятью» . Подсчет слабых сторон сообщества . МИТРА . Проверено 13 марта 2017 года .