stringtranslate.com

Проверка границ

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

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

Проверка диапазона

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

Проверка индекса

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

Ранние компилируемые языки программирования с возможностью проверки индекса включали ALGOL 60 , ALGOL 68 и Pascal , а также интерпретируемые языки программирования, такие как BASIC .

Многие языки программирования, такие как C , никогда не выполняют автоматическую проверку границ для повышения скорости. Однако это оставляет много ошибок выхода за пределы на единицу и переполнений буфера необнаруженными. Многие программисты считают, что эти языки жертвуют слишком многим ради быстрого выполнения. [1] В своей лекции на премии Тьюринга 1980 года К. А. Хоар описал свой опыт в разработке ALGOL 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.

Смотрите также

Ссылки

  1. ^ Коуэн, К.; Вейгл, Ф.; Калтон Пу; Битти, С.; Уолпол, Дж. (1999). «Переполнение буфера: атаки и защита от уязвимости десятилетия». Труды конференции и выставки DARPA по информационной выживаемости. DISCEX'00 . Том 2. С. 119–129. doi :10.1109/DISCEX.2000.821514. ISBN 978-0-7695-0490-2. S2CID  167759976.
  2. ^ "JS++ 0.9.0: Эффективный анализ ошибок выхода за пределы буфера во время компиляции – блог JS++". 11 января 2019 г. Архивировано из оригинала 12.01.2019.
  3. ^ JK Buckle (1978). Серия ICL 2900 (PDF) . Серия Macmillan Computer Science. стр. 17, 77. ISBN 978-0-333-21917-1. Архивировано из оригинала (PDF) 20 апреля 2018 г. . Получено 20 апреля 2018 г. .
  4. ^ Lap-Chung Lam; Tzi-Cker Chiueh (2005). "Проверка нарушения границ массива с использованием оборудования сегментации". Международная конференция по надежным системам и сетям 2005 года (DSN'05) . стр. 388–397. doi :10.1109/DSN.2005.25. ISBN 0-7695-2282-3. S2CID  6278708.

Внешние ссылки