Welcome! Log In Create A New Profile

Advanced

Re: Fwd: SIGABRT в самописном модуле

Maxim Dounin
February 24, 2016 07:50AM
Hello!

On Mon, Feb 22, 2016 at 12:25:42PM +0600, Alexander Uskov wrote:

[...]

> Есть самописный модуль со следующей задачей:
> Поймать обращение у url, если есть определенный GET параметр, то отдать файл с диска, поменяв в нем %V на значение параметра,
> если нет, то попытаться прочесть значение куки, если нет и его, то сгенерить этот параметр и сделать постоянный редирект на
> ?параметр=значение.
>
> Модуль писал года 2 назад, сам в C сильно плаваю.
> Скомпилинное решение сейчас работает в продакшине.
> Попытался пересобрать всё на новой машине (пересборка того, что сейчас работает дала такие-же результаты),
> появилась проблемма:

[...]

> Вылазит не на все запросы, а только под нагрузкой :( Поэтому дианностировать сильно сложно.
>
> Насколько смог отдиагностировать, проблема появляется именно в части, когда идет запрос без параметра.
> Т-е проблема где-то в следующем участке кода:
>
> // Проверяю, передано ли что в GET, передано ли GET['c'] и его длинну, если да, ни чего не делаю, иначе - редирект.
> if (r->args.len &&
> ngx_http_arg(r, (u_char *) zero_js_config->get_parm.data, zero_js_config->get_parm.len, &get_c) == NGX_OK &&
> get_c.len <=14 &&
> get_c.len>10) {
> /* void() */
> } else {
> // Отдаем редирект с кукой в GET
>
> // Пытаемся найти COOKIE['client_cc']
> n = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &zero_js_config->cookie_name, &cookie);
>
> // Если кука есть и ее длинна <=14 заносим значение в uniqid иначе генерим php_uniqid()
> if (n != NGX_DECLINED && cookie.len<=14) {
> ngx_sprintf(uniqid, "%V", &cookie);

При этом переменная uniqid как инициализируется?

Потому что ngx_sprintf() в общем случае строку не терминирует
нулём, и если uniqid просто объявлен как массив символов на стеке -
\0 в конце никто не обещал.

> } else {
> ngx_gettimeofday(&tv);
> sec = (int) tv.tv_sec;
> usec = (int) (tv.tv_usec % 0x100000);
> ngx_sprintf(uniqid, "%i%08xi%05xi", ngx_random() % 10, sec, usec);

И то же самое тут.

> }
>
> // создаем url для редиректа
> turl = ngx_pcalloc(r->pool, sizeof("?=") - 1 + zero_js_config->get_parm.len + sizeof(uniqid));
> if (turl == NULL) {
> return NGX_HTTP_INTERNAL_SERVER_ERROR;
> }
> ngx_sprintf(turl, "?%V=%s", &zero_js_config->get_parm, uniqid);

А вот тут вы печатаете uniqid как %s, т.е. как null-terminated
строку. Соответственно если \0 в конце не будет - будут проблемы.

> // Вставляем Location
> r->headers_out.location = ngx_list_push(&r->headers_out.headers);
> if (r->headers_out.location == NULL) {
> return NGX_ERROR;
> }
> r->headers_out.location->hash = 1;
> r->headers_out.location->key.len = sizeof("Location") - 1;
> r->headers_out.location->key.data = (u_char *) "Location";
> r->headers_out.location->value.len = sizeof("?=") - 1 + zero_js_config->get_parm.len + sizeof(uniqid);
> r->headers_out.location->value.data = turl;

Кроме того, вот тут используется sizeof(uniqid) вместо реальной
длины содержимого uniqid. Соответственно в выводе может быть не
всё либо дополнительный мусор.

Совет: используйте для строк ngx_str_t, с явным указанием длины
содержимого. Обе проблемы должны исчезнуть сами по себе.

[...]

--
Maxim Dounin
http://nginx.org/

_______________________________________________
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru
Subject Author Posted

Fwd: SIGABRT в самописном модуле

kornel February 22, 2016 02:34AM

Re: SIGABRT в самописном модуле

kornel February 22, 2016 09:08AM

Re: SIGABRT в самописном модуле

mva February 23, 2016 12:58PM

Re: SIGABRT в самописном модуле

kornel February 24, 2016 12:24AM

Re: Fwd: SIGABRT в самописном модуле

Maxim Dounin February 24, 2016 07:50AM

Re: SIGABRT в самописном модуле

kornel February 25, 2016 05:50AM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 129
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready