Проверка границ
Эта статья включает список общих ссылок , но в ней отсутствуют достаточные соответствующие встроенные цитаты . ( Март 2012 г. ) |
В компьютерном программировании проверка границ — это любой метод определения того, находится ли переменная в определенных пределах , прежде чем она будет использована. Обычно он используется для того, чтобы убедиться, что число соответствует заданному типу (проверка диапазона) или что переменная, используемая в качестве индекса массива , находится в пределах границ массива (проверка индекса). Неудачная проверка границ обычно приводит к генерации какого-то сигнала исключения .
Поскольку проверка границ во время каждого использования может занимать много времени, она выполняется не всегда. Устранение проверки границ — это метод оптимизации компилятора , который устраняет ненужную проверку границ.
Проверка диапазона [ править ]
Проверка диапазона — это проверка, позволяющая убедиться, что число находится в определенном диапазоне; например, чтобы гарантировать, что значение, которое будет присвоено 16-битному целому числу, находится в пределах емкости 16-битного целого числа (т. е. проверка на цикличность ). Это не совсем то же самое, что проверка типов . [ как? ] Другие проверки диапазона могут быть более строгими; например, может быть объявлено, что переменная, содержащая номер календарного месяца, принимает только диапазон от 1 до 12.
Проверка индекса [ править ]
Проверка индекса означает, что во всех выражениях, индексирующих массив, значение индекса проверяется на соответствие границам массива (которые были установлены при определении массива), и если индекс выходит за пределы, дальнейшее выполнение приостанавливается с помощью какая-то ошибка. Поскольку чтение или особенно запись значения за пределами массива может привести к сбою или сбою программы или к возникновению уязвимостей безопасности (см. Переполнение буфера ), проверка индекса является частью многих языков высокого уровня .
Ранние компилируемые языки программирования с возможностью проверки индексов включали АЛГОЛ 60 , АЛГОЛ 68 и Паскаль , а также интерпретируемые языки программирования, такие как BASIC .
Многие языки программирования, такие как C , никогда не выполняют автоматическую проверку границ для повышения скорости. Однако это оставляет необнаруженными многие ошибки, связанные с отклонением на единицу , и переполнение буфера . Многие программисты считают, что эти языки слишком многим жертвуют ради быстрого выполнения. [1] В своей на Премии Тьюринга лекции 1980 года К. А. Р. Хоар описал свой опыт разработки АЛГОЛА 60 , языка, включающего проверку границ, сказав:
Следствием этого принципа является то, что каждое появление каждого индекса каждой индексированной переменной каждый раз во время выполнения проверялось на соответствие как верхней, так и нижней объявленной границе массива. Много лет спустя мы спросили наших клиентов, хотят ли они, чтобы мы предоставили возможность отключать эти проверки в интересах эффективности производственных циклов. Они единогласно призвали нас не делать этого — они уже знали, как часто ошибки индексов возникают в производственных циклах, и неспособность их обнаружить может иметь катастрофические последствия. Я со страхом и ужасом отмечаю, что даже в 1980 году разработчики и пользователи языка не усвоили этот урок. В любой приличной отрасли техники несоблюдение таких элементарных мер предосторожности уже давно было бы противозаконно.
К основным языкам, обеспечивающим проверку во время выполнения, относятся Ada , C# , Haskell , Java , JavaScript , Lisp , PHP , Python , Ruby , Rust и Visual Basic . В языках D и OCaml предусмотрена проверка границ времени выполнения, которая включается или отключается с помощью переключателя компилятора. В C++ проверка во время выполнения не является частью языка, а является частью STL и включается с помощью переключателя компилятора (_GLIBCXX_DEBUG=1 или _LIBCPP_DEBUG=1). C# также поддерживает небезопасные регионы : разделы кода, которые (помимо прочего) временно приостанавливают проверку границ для повышения эффективности. Они полезны для ускорения небольших критичных по времени узких мест без ущерба для безопасности всей программы.
Язык программирования JS ++ способен анализировать, находится ли индекс массива или ключ карты вне границ во время компиляции, используя существующие типы , которые являются номинальным типом, описывающим, находится ли индекс или ключ в пределах границ или за пределами границ, и направляет генерацию кода. Было показано, что существующие типы увеличивают время компиляции всего на 1 мс. [2]
Проверка аппаратных ограничений [ править ]
Безопасность, добавляемая проверкой границ, обязательно требует затрат времени ЦП, если проверка выполняется программно; однако, если проверки могут выполняться аппаратно, то безопасность может быть обеспечена «бесплатно» без каких-либо затрат времени выполнения. Первой системой с проверкой аппаратных ограничений был мэйнфрейм серии ICL 2900, анонсированный в 1974 году. [3] Компьютер VAX имеет ассемблерную инструкцию INDEX для проверки индекса массива, которая принимает шесть операндов, каждый из которых может использовать любой режим адресации VAX. Компьютеры B6500 и аналогичные компьютеры Burroughs выполняли проверку привязки с помощью аппаратного обеспечения, независимо от того, какой компьютерный язык был скомпилирован для создания машинного кода. Ограниченное количество более поздних процессоров имеет специализированные инструкции для проверки границ, например, инструкция CHK2 в серии Motorola 68000 .
По крайней мере с 2005 года ведутся исследования относительно методов использования встроенного в x86 модуля управления виртуальной памятью для обеспечения безопасности доступа к массиву и буферу. [4] В 2015 году Intel представила расширения Intel MPX в своей процессорной архитектуре Skylake , которая хранит границы в регистре ЦП и таблице в памяти. По крайней мере, по состоянию на начало 2017 года GCC поддерживает расширения MPX.
См. также [ править ]
Ссылки [ править ]
- ^ Коуэн, К; Вагл, Ф; Калтон Пу; Битти, С; Уолпол, Дж (1999). «Переполнение буфера: атаки и защита от уязвимости десятилетия». Материалы конференции и выставки DARPA по информационной живучести. ДИСКЭКС'00 . Том. 2. С. 119–129. дои : 10.1109/DISCEX.2000.821514 . ISBN 978-0-7695-0490-2 . S2CID 167759976 .
- ^ «JS++ 0.9.0: эффективный анализ ошибок выхода за границы во время компиляции — блог JS++» . 11 января 2019 г. Архивировано из оригинала 12 января 2019 г.
- ^ Дж. К. Бакл (1978). Серия ICL 2900 (PDF) . Серия Macmillan по информатике. стр. 17, 77. ISBN. 978-0-333-21917-1 . Архивировано из оригинала (PDF) 20 апреля 2018 года . Проверено 20 апреля 2018 г.
- ^ Лап-Чунг Лам; Ци-Ккер Чиуэ (2005). «Проверка нарушения границ массива с использованием оборудования сегментации». 2005 Международная конференция по надежным системам и сетям (DSN'05) . стр. 388–397. дои : 10.1109/DSN.2005.25 . ISBN 0-7695-2282-3 . S2CID 6278708 .
Внешние ссылки [ править ]
- « О преимуществах тегированной архитектуры », IEEE Transactions On Computers, том C-22, номер 7, июль 1973 г.
- « Старая одежда императора , заархивированная 2 октября 2017 г. в Wayback Machine », лекция на премию Тьюринга ACM 1980 г., CACM, том 24, номер 2, февраль 1981 г., стр. 75–83.
- « Скрытая копия: проверка времени выполнения программ на языке C », Сэмюэл К. Кендалл, Материалы конференции USENIX , лето 1983 г.
- « Проверка границ для C », Ричард Джонс и Пол Келли, Имперский колледж, июль 1995 г.
- « Обзор безопасности MCP корпоративных серверов ClearPath », Unisys, апрель 2006 г.
- « Безопасная виртуальная архитектура: безопасная среда выполнения для обычных операционных систем », Джон Крисвелл, Эндрю Ленхарт, Динакар Дхурджати, Викрам Адве, SOSP'07 21-й симпозиум ACM по принципам операционных систем, 2007 г.
- « Fail-Safe C », Ютака Оива. Реализация компилятора Full ANSI-C, безопасного для памяти. Конференция ACM SIGPLAN по разработке и реализации языков программирования (PLDI2009), июнь 2009 г.
- “ address-sanitizer ”, Timur Iskhodzhanov, Alexander Potapenko, Alexey Samsonov, Kostya Serebryany, Evgeniy Stepanov, Dmitriy Vyukov, LLVM Dev Meeting, November 18, 2011.
- Безопасная библиотека C ограниченных API
- «Безопасная библиотека C» . Журнал доктора Добба . 20 февраля 2009 года. Архивировано из оригинала 2 декабря 2013 года . Проверено 13 ноября 2012 г.
- Safe C API — краткое решение проблемы переполнения буфера, The OWASP Foundation, OWASP AppSec, Пекин, 2011 г.
- Руководство по библиотеке GNU C++ Макросы
- Документация по libc++ 11.0 Режим отладки