Mercurial > hg > nginx-quic
changeset 6272:b6a665bf858a
HTTP/2: fix indirect reprioritization.
Previously, streams that were indirectly reprioritized (either because of
a new exclusive dependency on their parent or because of removal of their
parent from the dependency tree), didn't have their pointer to the parent
node updated.
This broke detection of circular dependencies and, as a result, nginx
worker would crash due to stack overflow whenever such dependency was
introduced.
Found with afl-fuzz.
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
author | Piotr Sikora <piotrsikora@google.com> |
---|---|
date | Thu, 01 Oct 2015 20:25:55 -0700 |
parents | 22ee99422329 |
children | 60f916da7294 |
files | src/http/v2/ngx_http_v2.c |
diffstat | 1 files changed, 13 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -2914,11 +2914,14 @@ ngx_http_v2_get_closed_node(ngx_http_v2_ weight += child->weight; } + parent = node->parent; + for (q = ngx_queue_head(&node->children); q != ngx_queue_sentinel(&node->children); q = ngx_queue_next(q)) { child = ngx_queue_data(q, ngx_http_v2_node_t, queue); + child->parent = parent; child->weight = node->weight * child->weight / weight; if (child->weight == 0) { @@ -2926,8 +2929,6 @@ ngx_http_v2_get_closed_node(ngx_http_v2_ } } - parent = node->parent; - if (parent == NGX_HTTP_V2_ROOT) { node->rank = 0; node->rel_weight = 1.0; @@ -3940,8 +3941,8 @@ static void ngx_http_v2_set_dependency(ngx_http_v2_connection_t *h2c, ngx_http_v2_node_t *node, ngx_uint_t depend, ngx_uint_t exclusive) { - ngx_queue_t *children; - ngx_http_v2_node_t *parent, *next; + ngx_queue_t *children, *q; + ngx_http_v2_node_t *parent, *child, *next; parent = depend ? ngx_http_v2_get_node_by_id(h2c, depend, 0) : NULL; @@ -4003,6 +4004,14 @@ ngx_http_v2_set_dependency(ngx_http_v2_c } if (exclusive) { + for (q = ngx_queue_head(children); + q != ngx_queue_sentinel(children); + q = ngx_queue_next(q)) + { + child = ngx_queue_data(q, ngx_http_v2_node_t, queue); + child->parent = node; + } + ngx_queue_add(&node->children, children); ngx_queue_init(children); }