Thanks for your review.<br><br>this is new patch:<br><br>Index: src/http/modules/ngx_http_fastcgi_module.c<br>===================================================================<br>--- src/http/modules/ngx_http_fastcgi_module.c (revision 3937)<br>
+++ src/http/modules/ngx_http_fastcgi_module.c (working copy)<br>@@ -165,7 +165,10 @@<br> static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post,<br> void *data);<br> <br>+static ngx_inline ngx_int_t ngx_http_fastcgi_ignored_header(ngx_table_elt_t **ignored,<br>
+ ngx_table_elt_t *header, ngx_uint_t header_params);<br> <br>+<br> static ngx_conf_post_t ngx_http_fastcgi_lowat_post =<br> { ngx_http_fastcgi_lowat_check };<br> <br>@@ -684,6 +687,26 @@<br> #endif<br> <br> <br>
+static ngx_inline ngx_int_t<br>
+ngx_http_fastcgi_ignored_header(ngx_table_elt_t **ignored, ngx_table_elt_t *header, ngx_uint_t header_params)<br>+{<br>+ ngx_uint_t n;<br>+ ngx_table_elt_t *h;<br>+<br>+ for (n = 0; n < header_params; n++) {<br>
+ h = ignored[n];<br>+<br>+ if (header->key.len == h->key.len<br>+ && ngx_memcmp(header->lowcase_key, h->lowcase_key, header->key.len) == 0) {<br>+<br>+ return NGX_OK;<br>
+ }<br>+ }<br>+<br>+ return NGX_DECLINED;<br>+}<br>+<br>+<br> static ngx_int_t<br> ngx_http_fastcgi_create_request(ngx_http_request_t *r)<br> {<br>@@ -784,6 +807,11 @@<br> }<br> <br> if (ngx_hash_find(&flcf->headers_hash, hash, lowcase_key, n)) {<br>
+<br>+ if (ngx_http_fastcgi_ignored_header(ignored, &header[i], header_params) == NGX_OK) {<br>+ continue;<br>+ }<br>+<br> ignored[header_params++] = &header[i];<br>
continue;<br> }<br>@@ -915,10 +943,8 @@<br> i = 0;<br> }<br> <br>- for (n = 0; n < header_params; n++) {<br>- if (&header[i] == ignored[n]) {<br>
- goto next;<br>- }<br>+ if (ngx_http_fastcgi_ignored_header(ignored, &header[i], header_params) == NGX_OK) {<br>+ continue;<br> }<br> <br> key_len = sizeof("HTTP_") - 1 + header[i].key.len;<br>
@@ -964,9 +990,6 @@<br> "fastcgi param: \"%*s: %*s\"",<br> key_len, b->last - (key_len + val_len),<br> val_len, b->last - val_len);<br>
- next:<br>-<br>- continue;<br> }<br> }<br><br><br><br><div class="gmail_quote">On Wed, Jun 1, 2011 at 7:56 AM, Maxim Dounin <span dir="ltr"><<a href="mailto:mdounin@mdounin.ru" target="_blank">mdounin@mdounin.ru</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hello!<br>
<div><br>
On Wed, Jun 01, 2011 at 12:24:10AM +0800, Simon Liu wrote:<br>
<br>
> this bug will give rise to nginx(version >= 0.8.40) core dump, and it was<br>
> caused by this feature:<br>
><br>
> *) Feature: a "fastcgi_param" directive with value starting with<br>
> "HTTP_" overrides a client request header line.<br>
><br>
><br>
> When we difine fastcgi_param directive with value starting with "HTTP_",<br>
> nginx malloc a array(size is header_params that is number of value starting<br>
> with "HTTP_"), and if request header contain this value(HTTTP_xxx), nginx<br>
> will add this header pointer to array, but if header is duplicated, this<br>
> array will cross-border.<br>
><br>
> e.g. if the config contain this directive (fastcgi_param HTTP_HOST<br>
> $http_host), and then request header send multi-duplicated header(Host),<br>
> nginx will core dump.<br>
<br>
</div>Yes, thank you, it's known problem.<br>
<br>
[...]<br>
<div><br>
> +static ngx_inline ngx_int_t<br>
> +ngx_http_fastcgi_ignored_header(ngx_uint_t hash, ngx_uint_t header_params,<br>
> ngx_uint_t *ignored)<br>
> +{<br>
> + ngx_uint_t n;<br>
> +<br>
> + for (n = 0; n < header_params; n++) {<br>
> + if (hash == ignored[n]) {<br>
> + return NGX_OK;<br>
<br>
</div>You can't rely on hash here, as it's expected to have collisions.<br>
<br>
[...]<br>
<div><br>
> @@ -2374,7 +2363,22 @@<br>
><br>
> hk->key.len = src[i].key.len - 5;<br>
> hk->key.data = src[i].key.data + 5;<br>
> - hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len);<br>
> +<br>
> + params_hash = 0;<br>
> + for (n = 5; n < src[i].key.len; n++) {<br>
> + ch = src[i].key.data[n];<br>
> +<br>
> + if (ch >= 'A' && ch <= 'Z') {<br>
> + ch |= 0x20;<br>
> +<br>
> + } else if (ch == '_') {<br>
> + ch = '-';<br>
> + }<br>
<br>
</div>This makes impossible to overwrite headers with real underscores<br>
(if underscores_in_headers are allowed).<br>
<br>
Maxim Dounin<br>
<br>
_______________________________________________<br>
nginx-devel mailing list<br>
<a href="mailto:nginx-devel@nginx.org" target="_blank">nginx-devel@nginx.org</a><br>
<a href="http://nginx.org/mailman/listinfo/nginx-devel" target="_blank">http://nginx.org/mailman/listinfo/nginx-devel</a><br>
</blockquote></div><br><br clear="all"><br>-- <br>博观约取<br><br>豆瓣:<a href="http://www.douban.com/people/mustang/" target="_blank">www.douban.com/people/mustang/</a><br><br>blog: <a href="http://www.pagefault.info" target="_blank">www.pagefault.info</a><br>
<br>twitter: <a href="http://www.twitter.com/minibobo" target="_blank">www.twitter.com/minibobo</a><br><br>sina 微博: <a href="http://www.weibo.com/diaoliang" target="_blank">www.weibo.com/diaoliang</a><br><br>