Spec-Zone.ru › GCC 11

Следующее: Другие встроенные функции, предоставляемые GCC, Предыдущее: Расширения модели памяти x86, специфичные для транзакционной памяти, Вверх: Расширения семейства языков C [Содержание][Индекс]

6.58 Встроенные функции проверки размера объектов ¶

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

Встроенная функция: size_t __builtin_object_size (const void * ptr, int type) ¶

является встроенной конструкцией, которая возвращает количество байтов от ptr до конца объекта, на который указывает указатель ptr (если оно известно на этапе компиляции). Для определения размеров динамически выделенных объектов функция полагается на функции выделения, вызываемые для получения памяти, которая должна быть объявлена с атрибутом alloc_size (см. Общие атрибуты функций). __builtin_object_size никогда не оценивает свои аргументы на побочные эффекты. Если в них есть какие-либо побочные эффекты, она возвращает (size_t) -1 для type 0 или 1 и (size_t) 0 для type 2 или 3. Если ptr может указывать на несколько объектов, и все они известны на этапе компиляции, возвращаемое число — это максимум оставшихся байтов в этих объектах, если type & 2 равно 0, и минимум, если оно отлично от нуля. Если на этапе компиляции невозможно определить, на какие объекты указывает ptr, то __builtin_object_size должно вернуть (size_t) -1 для type 0 или 1 и (size_t) 0 для type 2 или 3.

type — целочисленная константа от 0 до 3. Если младший бит равен нулю, объекты — целые переменные, если он установлен, ближайшее окружающее подобъект считается объектом, на который указывает указатель. Второй бит определяет, вычисляется ли максимум или минимум оставшихся байтов.

struct V { char buf1[10]; int b; char buf2[10]; } var;
char *p = &var.buf1[1], *q = &var.b;

/* Here the object p points to is var.  */
assert (__builtin_object_size (p, 0) == sizeof (var) - 1);
/* The subobject p points to is var.buf1.  */
assert (__builtin_object_size (p, 1) == sizeof (var.buf1) - 1);
/* The object q points to is var.  */
assert (__builtin_object_size (q, 0)
        == (char *) (&var + 1) - (char *) &var.b);
/* The subobject q points to is var.b.  */
assert (__builtin_object_size (q, 1) == sizeof (var.b));

Для многих стандартных функций работы со строками, например, для memcpy __builtin___memcpy_chk предоставлена встроенная функция. Эта встроенная функция имеет дополнительный последний аргумент, который является количеством оставшихся байтов в объекте, на который указывает аргумент dest, или (size_t) -1 если размер неизвестен.

Встроенные функции оптимизируются в обычные функции работы со строками, такие как memcpy, если последний аргумент (size_t) -1 или если на этапе компиляции известно, что объект назначения не будет переполнен. Если компилятор на этапе компиляции определит, что объект всегда будет переполнен, он выведет предупреждение.

Предполагаемое использование, например,

#undef memcpy
#define bos0(dest) __builtin_object_size (dest, 0)
#define memcpy(dest, src, n) \
  __builtin___memcpy_chk (dest, src, n, bos0 (dest))

char *volatile p;
char buf[10];
/* It is unknown what object p points to, so this is optimized
   into plain memcpy - no checking is possible.  */
memcpy (p, "abcde", n);
/* Destination is known and length too.  It is known at compile
   time there will be no overflow.  */
memcpy (&buf[5], "abcde", 5);
/* Destination is known, but the length is not known at compile time.
   This will result in __memcpy_chk call that can check for overflow
   at run time.  */
memcpy (&buf[5], "abcde", n);
/* Destination is known and it is known at compile time there will
   be overflow.  There will be a warning and __memcpy_chk call that
   will abort the program at run time.  */
memcpy (&buf[6], "abcde", 5);

Аналогичные встроенные функции предоставляются для memcpy, mempcpy, memmove, memset, strcpy, stpcpy, strncpy, strcat и strncat.

Также есть встроенные функции проверки для функций форматированного вывода.

int __builtin___sprintf_chk (char *s, int flag, size_t os, const char *fmt, ...);
int __builtin___snprintf_chk (char *s, size_t maxlen, int flag, size_t os,
                              const char *fmt, ...);
int __builtin___vsprintf_chk (char *s, int flag, size_t os, const char *fmt,
                              va_list ap);
int __builtin___vsnprintf_chk (char *s, size_t maxlen, int flag, size_t os,
                               const char *fmt, va_list ap);

Дополнительный аргумент flag передается неизменным функциям __sprintf_chk и т. д. и может содержать зависящие от реализации флаги о дополнительных мерах безопасности, которые может предпринять функция проверки, такие как обработка %n по-разному.

Аргумент os — это размер объекта, на который указывает s, как и в других встроенных функциях. Однако есть небольшое отличие в поведении, если os — (size_t) -1, встроенные функции оптимизируются в не проверяющие функции только если flag равно 0, в противном случае функция проверки вызывается с аргументом os, установленным в (size_t) -1.

Кроме того, есть встроенные функции проверки __builtin___printf_chk, __builtin___vprintf_chk, __builtin___fprintf_chk и __builtin___vfprintf_chk. Они имеют только один дополнительный аргумент flag перед строкой форматирования fmt. Если компилятор может оптимизировать их в функции fputc и т. д., он это делает, в противном случае вызывается функция проверки, и аргумент flag передается ей.

Следующее: Другие встроенные функции, предоставляемые GCC, Предыдущее: Расширения модели памяти x86, специфичные для транзакционной памяти, Вверх: Расширения семейства языков C [Содержание][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-11.4.0/gcc/Object-Size-Checking.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API