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

В компьютерном программировании , проверки границ какой - либо метод обнаружения ли переменная находится в некоторых пределах , прежде чем она используется. Обычно он используется для обеспечения того, чтобы число соответствовало заданному типу (проверка диапазона) или чтобы переменная, используемая в качестве индекса массива, находилась в границах массива (проверка индекса). Неудачная проверка границ обычно приводит к генерации какого-либо сигнала исключения .

Поскольку выполнение проверки границ при каждом использовании занимает много времени, это не всегда делается. Устранение проверки границ - это метод оптимизации компилятора , который исключает проверку ненужных границ.

Проверка диапазона [ править ]

Проверка диапазона - это проверка, чтобы убедиться, что число находится в определенном диапазоне; например, чтобы гарантировать, что значение, которое будет присвоено 16-битному целому числу, находится в пределах емкости 16-битного целого числа (т. е. проверка против циклического перехода ). Это не совсем то же самое, что проверка типов . Другие проверки диапазона могут быть более строгими; например, переменная для хранения номера календарного месяца может быть объявлена ​​как принимающая только диапазон от 1 до 12.

Проверка индекса [ править ]

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

Паскаль, Фортран и Java имеют возможность проверки индексов. В компьютере VAX есть инструкция сборки INDEX для проверки индекса массива, которая принимает шесть операндов, каждый из которых может использовать любой режим адресации VAX. B6500 и подобные компьютеры Burroughs выполняли проверку привязки с помощью оборудования, независимо от того, какой компьютерный язык был скомпилирован для создания машинного кода. Ограниченное количество более поздних процессоров имеет специализированные инструкции для проверки границ, например, инструкция CHK2 на Motorola серии 68000 .

Многие языки программирования , такие как C , никогда не выполняют автоматическую проверку границ для повышения скорости. Тем не менее, это оставляет невыявленными многие одноразовые ошибки и переполнение буфера . Многие программисты считают, что эти языки слишком многим жертвуют ради быстрого выполнения. [1] В своей лекции 1980 года по Премии Тьюринга К.Р. Хоар описал свой опыт разработки Алгола 60 , языка, который включал проверку границ, сказав:

Следствием этого принципа является то, что каждое вхождение каждого нижнего индекса каждой переменной с нижним индексом каждый раз проверялось во время выполнения как по верхней, так и по нижней объявленным границам массива. Много лет спустя мы спросили наших клиентов, не хотят ли они, чтобы мы предоставили возможность отключать эти проверки в интересах эффективности производственных циклов. Они единодушно призвали нас не делать этого - они уже знали, как часто ошибки индексации возникают в производственных циклах, когда их не обнаружение может иметь катастрофические последствия. Я со страхом и ужасом отмечаю, что даже в 1980 году разработчики и пользователи языков не усвоили этот урок. В любой респектабельной области техники несоблюдение таких элементарных мер предосторожности уже давно было бы нарушением закона.

Основные языки, которые принудительно проверяют время выполнения, включают Ada , C # , Haskell , Java , JavaScript , Lisp , PHP , Python , Ruby и Visual Basic . В языках D и OCaml есть проверка границ времени выполнения, которая включается или выключается переключателем компилятора. В C ++ проверка времени выполнения не является частью языка, а является частью STL и включается переключателем компилятора (_GLIBCXX_DEBUG = 1 или _LIBCPP_DEBUG = 1). C # также поддерживает небезопасные регионы: разделы кода, которые (среди прочего) временно приостанавливают проверку границ для повышения эффективности. Они полезны для ускорения небольших критических по времени узких мест без ущерба для безопасности всей программы.

Язык программирования JS ++ может анализировать, находится ли индекс массива или ключ карты за пределами границ во время компиляции, используя существующие типы , которые являются номинальным типом, описывающим, находится ли индекс или ключ в пределах или за пределами, и руководит генерацией кода. Было показано, что существующие типы добавляют к времени компиляции только 1 мсек. [2]

Проверка границ оборудования [ править ]

Безопасность, добавленная проверкой границ, обязательно стоит процессорного времени, если проверка выполняется программно; однако, если проверки могут выполняться аппаратными средствами, безопасность может быть предоставлена ​​«бесплатно» без затрат времени выполнения. Ранней системой с проверкой аппаратных границ был мэйнфрейм серии ICL 2900, анонсированный в 1974 году. [3] Исследования ведутся по крайней мере с 2005 года в отношении методов использования встроенного модуля управления виртуальной памятью x86 для обеспечения безопасности доступа к массивам и буферам. [4] В 2015 году Intel представила свои расширения Intel MPX в архитектуре процессора Skylake , которая хранит границы в регистре ЦП и таблице в памяти. По состоянию на начало 2017 года по крайней мере GCC поддерживает расширения MPX.

См. Также [ править ]

  • Динамический анализ кода
  • Обнаружение ошибок во время выполнения
  • Статический анализ кода

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

  1. ^ Коуэн, C; Wagle, F; Calton Pu; Битти, S; Уолпол, Дж (1999). «Переполнение буфера: атаки и защита уязвимости десятилетия». Материалы конференции и выставки по информационной живучести DARPA. DISCEX'00 . 2 . С. 119–129. DOI : 10,1109 / DISCEX.2000.821514 . ISBN 978-0-7695-0490-2.
  2. ^ "JS ++ 0.9.0: Эффективный анализ ошибок вне пределов времени компиляции - Блог JS ++" . Архивировано из оригинала на 2019-01-12.
  3. ^ JK Пряжка (1978). Серия ICL 2900 (PDF) . Серия Macmillan Computer Science. С. 17, 77. ISBN  978-0-333-21917-1. Проверено 20 апреля 2018 года .
  4. ^ Лап-Чунг Лам; Ци-Чкер Чиу (2005). «Проверка нарушения границ массива с помощью оборудования для сегментации». 2005 Международная конференция по надежным системам и сетям (DSN'05) . С. 388–397. DOI : 10.1109 / DSN.2005.25 . ISBN 0-7695-2282-3.

Внешние ссылки [ править ]

  • « О преимуществах архитектуры с тегами », «Транзакции IEEE на компьютерах», том C-22, номер 7, июль 1973 г.
  • « Старая одежда императора », Лекция по Премии Тьюринга ACM 1980 г., том 24 CACM, номер 2, февраль 1981 г., стр. 75–83.
  • « Скрытая копия: проверка времени выполнения для программ C », Сэмюэл К. Кендалл, Труды конференции USENIX Summer 1983.
  • « Проверка границ для C », Ричард Джонс и Пол Келли, Имперский колледж, июль 1995 года.
  • « Обзор безопасности MCP серверов ClearPath Enterprise Servers », Unisys, апрель 2006 г.
  • « Безопасная виртуальная архитектура: безопасная среда выполнения для стандартных операционных систем », Джон Крисвелл, Эндрю Ленхарт, Динакар Дурджати, Викрам Адве, 21-й симпозиум ACM по принципам операционных систем SOSP'07, 2007.
  • « Fail-Safe C », Ютака Оива. Реализация безопасного для памяти полного компилятора ANSI-C. Конференция ACM SIGPLAN по проектированию и реализации языков программирования (PLDI2009), июнь 2009 г.
  • « Address-sanitizer », Тимур Исходжанов, Александр Потапенко, Алексей Самсонов, Костя Серебряный, Евгений Степанов, Дмитрий Вьюков, LLVM Dev Meeting, 18 ноября 2011 г.
  • Безопасная библиотека ограниченных API на языке C
  • «Библиотека Safe C» . Журнал доктора Добба . 20 февраля 2009 года в архив с оригинала на 2 декабря 2013 года . Проверено 13 ноября 2012 года .
  • Safe C API - Краткое решение проблемы переполнения буфера, Фонд OWASP, OWASP AppSec, Пекин, 2011 г.
  • Макросы руководства библиотеки GNU C ++
  • Документация по libc ++ 11.0 Режим отладки