Spec-Zone.ru › GCC 6

6.55 Функции проверки размера объектов (встроенные)

GCC реализует ограниченный механизм защиты от переполнения буфера, который может предотвратить некоторые атаки переполнения буфера.

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

является встроенной конструкцией, которая возвращает постоянное количество байтов от ptr до конца объекта, к которому указывает указатель ptr (если это известно на этапе компиляции). __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 передается ей.

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

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

Spec-Zone.ru

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