Почему этот код в nginx не вызывает переполнения буфера? - PullRequest
1 голос
/ 22 июня 2011

Цитируется из ngx_hash.c :

ngx_strlow(elt->name, names[n].key.data, names[n].key.len);

Который копирует строчную строку в elt->name.

Здесь elt имеет тип ngx_hash_elt_t *:

typedef struct {
    void             *value;
    u_short           len;
    u_char            name[1];
} ngx_hash_elt_t;

Как видите, name имеет ширину всего 1, IMO ngx_strlow вызовет переполнение буфера, но на самом деле это работает без проблем, кто-нибудь может объяснить это?

Ответы [ 4 ]

2 голосов
/ 22 июня 2011

Обычно структура такого рода определяется так, что программист (если она хочет len = 100) может перейти:

ngx_hash_elt_t *X;
X = malloc(sizeof(ng_has_elt_t)+99);

В этом случае он все еще действителен и имеет смысл для пользователя и библиотеки для ссылкиX.name, потому что это указатель на начало строки.

1 голос
/ 22 июня 2011

Вероятно, структура выделяется в куче с помощью malloc ().

Это может работать примерно так:

size_t decent_length = <something big enough to hold a string>;

ngx_hash_elt_t *elt = malloc (sizeof (*p) + decent_length);
0 голосов
/ 22 июня 2011

Если elt был выделен как

elt = (ngx_hash_elt_t*)malloc(sizeof(ngx_hash_elt_t));

, то это приведет к переполнению строк длиннее 1. Однако, скорее всего, он был выделен как:

elt = (ngx_hash_elt_t*)malloc(sizeof(ngx_hash_elt_t) + maximum_possible_length);

,так что переполнения нет.

0 голосов
/ 22 июня 2011

Это хитрость для создания буферов переменной длины с C. Сделайте последний элемент длиной в 1 байт и выделите больше. Для этой структуры выделение ngx_hash_elt_t может быть выполнено следующим образом, например:

ngx_hash_elt_t* alloc_hash_elt(int name_len)
{
    return malloc(sizeof(ngx_hash_elt_t) - 1 + name_len);
}

Дополнительное пространство, которое вы выделяете, теперь может безопасно использоваться элементом name.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...