comparison src/http/ngx_http_spdy.c @ 5323:2be1a9ce9d8e

SPDY: fixed corruption of headers with names longer than 255. It is a bad idea to put zero byte in position where the length of the next header name can be stored before it was parsed.
author Valentin Bartenev <vbart@nginx.com>
date Thu, 15 Aug 2013 19:14:58 +0400
parents 7542b72fe4b1
children 8ef1722143dc
comparison
equal deleted inserted replaced
5322:bdb3588681c9 5323:2be1a9ce9d8e
807 buf = r->header_in; 807 buf = r->header_in;
808 808
809 sc->zstream_in.next_in = pos; 809 sc->zstream_in.next_in = pos;
810 sc->zstream_in.avail_in = size; 810 sc->zstream_in.avail_in = size;
811 sc->zstream_in.next_out = buf->last; 811 sc->zstream_in.next_out = buf->last;
812
813 /* one byte is reserved for null-termination of the last header value */
812 sc->zstream_in.avail_out = buf->end - buf->last - 1; 814 sc->zstream_in.avail_out = buf->end - buf->last - 1;
813 815
814 z = inflate(&sc->zstream_in, Z_NO_FLUSH); 816 z = inflate(&sc->zstream_in, Z_NO_FLUSH);
815 817
816 if (z == Z_NEED_DICT) { 818 if (z == Z_NEED_DICT) {
910 ngx_http_spdy_close_stream(sc->stream, 912 ngx_http_spdy_close_stream(sc->stream,
911 NGX_HTTP_INTERNAL_SERVER_ERROR); 913 NGX_HTTP_INTERNAL_SERVER_ERROR);
912 return ngx_http_spdy_state_headers_error(sc, pos, end); 914 return ngx_http_spdy_state_headers_error(sc, pos, end);
913 } 915 }
914 916
917 /* null-terminate the last processed header name or value */
918 *buf->pos = '\0';
919
915 buf = r->header_in; 920 buf = r->header_in;
916 921
917 sc->zstream_in.next_out = buf->last; 922 sc->zstream_in.next_out = buf->last;
923
924 /* one byte is reserved for null-termination */
918 sc->zstream_in.avail_out = buf->end - buf->last - 1; 925 sc->zstream_in.avail_out = buf->end - buf->last - 1;
919 926
920 z = inflate(&sc->zstream_in, Z_NO_FLUSH); 927 z = inflate(&sc->zstream_in, Z_NO_FLUSH);
921 928
922 if (z != Z_OK) { 929 if (z != Z_OK) {
993 1000
994 if (!complete) { 1001 if (!complete) {
995 return ngx_http_spdy_state_save(sc, pos, end, 1002 return ngx_http_spdy_state_save(sc, pos, end,
996 ngx_http_spdy_state_headers); 1003 ngx_http_spdy_state_headers);
997 } 1004 }
1005
1006 /* null-terminate the last header value */
1007 *buf->pos = '\0';
998 1008
999 ngx_http_spdy_run_request(r); 1009 ngx_http_spdy_run_request(r);
1000 1010
1001 return ngx_http_spdy_state_complete(sc, pos, end); 1011 return ngx_http_spdy_state_complete(sc, pos, end);
1002 } 1012 }
1934 1944
1935 if (!len) { 1945 if (!len) {
1936 return NGX_HTTP_PARSE_INVALID_HEADER; 1946 return NGX_HTTP_PARSE_INVALID_HEADER;
1937 } 1947 }
1938 1948
1949 /* null-terminate the previous header value */
1950 *p = '\0';
1951
1939 p += NGX_SPDY_NV_NLEN_SIZE; 1952 p += NGX_SPDY_NV_NLEN_SIZE;
1940 1953
1941 r->header_name_end = p + len; 1954 r->header_name_end = p + len;
1942 r->lowcase_index = len; 1955 r->lowcase_index = len;
1943 r->invalid_header = 0; 1956 r->invalid_header = 0;
2002 len = ngx_spdy_frame_parse_uint16(p); 2015 len = ngx_spdy_frame_parse_uint16(p);
2003 2016
2004 if (!len) { 2017 if (!len) {
2005 return NGX_ERROR; 2018 return NGX_ERROR;
2006 } 2019 }
2020
2021 /* null-terminate header name */
2022 *p = '\0';
2007 2023
2008 p += NGX_SPDY_NV_VLEN_SIZE; 2024 p += NGX_SPDY_NV_VLEN_SIZE;
2009 2025
2010 r->header_end = p + len; 2026 r->header_end = p + len;
2011 2027
2161 2177
2162 h->hash = r->header_hash; 2178 h->hash = r->header_hash;
2163 2179
2164 h->key.len = r->lowcase_index; 2180 h->key.len = r->lowcase_index;
2165 h->key.data = r->header_name_start; 2181 h->key.data = r->header_name_start;
2166 h->key.data[h->key.len] = '\0';
2167 2182
2168 h->value.len = r->header_size; 2183 h->value.len = r->header_size;
2169 h->value.data = r->header_start; 2184 h->value.data = r->header_start;
2170 h->value.data[h->value.len] = '\0';
2171 2185
2172 h->lowcase_key = h->key.data; 2186 h->lowcase_key = h->key.data;
2173 2187
2174 return NGX_OK; 2188 return NGX_OK;
2175 } 2189 }