Opened 8 years ago

Closed 8 years ago

#995 closed defect (invalid)

The probable error in ngx_conf_parse (ngx_palloc?) implementation

Reported by: Dmitry Afanasiev Owned by:
Priority: critical Milestone:
Component: nginx-core Version: 1.11.x
Keywords: Cc:
uname -a: Windows Server 2008R2 (x64)
nginx -V: nginx version: nginx/1.11.2
built by cl 18.00.40629 for x86
built with OpenSSL 1.0.2h 3 May 2016
TLS SNI support enabled
configure arguments: --with-debug --crossbuild=win32 --with-cc=cl --builddir=obj
s --prefix= --conf-path=conf/nginx.conf --pid-path=logs/nginx.pid --http-log-pat
h=logs/access.log --error-log-path=logs/error.log --sbin-path=nginx.exe --http-c
lient-body-temp-path=temp/client_body_temp --http-proxy-temp-path=temp/proxy_tem
p --http-fastcgi-temp-path=temp/fastcgi_temp --with-cc-opt=-DFD_SETSIZE=1024 --w
ith-pcre=objs/libs/pcre-8.38 --with-zlib=objs/libs/zlib-1.2.8 --with-openssl=obj
s/libs/openssl-1.0.2h --with-select_module --with-http_ssl_module --with-ipv6 --
with-openssl-opt=enable-tlsext --with-openssl-opt=no-asm --with-stream --with-st
ream_ssl_module --with-http_gzip_static_module --with-http_v2_module --with-ipv6

Description

Enviroment:

  • nginx build with --crossbuild=win32 switch using VS2013 (cl v18.00.40629)
  • OpenSSL 1.0.2h
  • PCRE 8.38
  • zlib 1.2.8
  • in description I have nginx build from rev6586, but build from tag 1.11.1 have same problem

nginx.config:

#user  nobody;
worker_processes  1;
pid temp/nginx.pid;
daemon off;
master_process off;
error_log logs/error.log debug;

events {
}

http {
    include       mime.types;

    server {
			listen 8745;
			server_name  localhost;
    }
}

(mime.types file from original sources)

Now test configuration using nginx -t command: nginx report error and crash (Access vialation exception).
After add #define NGX_DEBUG_PALLOC 1 in ngx_palloc.c this test work ok (huh?).

error stack trace:

 	nginx.exe!free(void * pBlock) Line 51	C
>	nginx.exe!ngx_conf_parse(ngx_conf_s * cf, ngx_str_t * filename) Line 298	C
 	nginx.exe!ngx_conf_include(ngx_conf_s * cf, ngx_command_s * cmd, void * conf) Line 799	C
 	nginx.exe!ngx_conf_handler(ngx_conf_s * cf, int last) Line 427	C
 	nginx.exe!ngx_conf_parse(ngx_conf_s * cf, ngx_str_t * filename) Line 283	C
 	nginx.exe!ngx_http_block(ngx_conf_s * cf, ngx_command_s * cmd, void * conf) Line 237	C
 	nginx.exe!ngx_conf_handler(ngx_conf_s * cf, int last) Line 427	C
 	nginx.exe!ngx_conf_parse(ngx_conf_s * cf, ngx_str_t * filename) Line 283	C
 	nginx.exe!ngx_init_cycle(ngx_cycle_s * old_cycle) Line 274	C
 	nginx.exe!main(int argc, char * const * argv) Line 278	C

hmm... i'm try to debug...
0) add DebugBreak(); at first line function

ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)

0.1) run nginx -t and attach VS Debugger
1) buffer allocated in ~line145 (when filename pointer point to "C:\blablabla\...\mime.types" full filename):

buf.start = ngx_alloc(NGX_CONF_BUFFER, cf->log);  //allocation, buf.start=0x00572F70

2) I set memory write (4bytes) break on *buf.start DWORD (at 0x00572F70)
AND also add breakpoint on line where buffer should free:

    if (filename) {
        if (cf->conf_file->buffer->start) {   //breakpoint here
            ngx_free(cf->conf_file->buffer->start);   //deallocation as I see... maybe im wrong?

3) After that im continue exection
4) Boom! VS stop execution on memory write break, but before 'deallcation' was called:
Line:

    content_type = ngx_palloc(cf->pool, sizeof(ngx_str_t));  //content_type was optimized by VS compiller, but it look like that it was 'allocation' in already allocated memory?!
    if (content_type == NULL) {
        return NGX_CONF_ERROR;
    }

    *content_type = value[0]; //here we stay

StackTrace:

>	nginx.exe!ngx_http_core_type(ngx_conf_s * cf, ngx_command_s * dummy, void * conf) Line 3358	C
 	nginx.exe!ngx_conf_parse(ngx_conf_s * cf, ngx_str_t * filename) Line 270	C
 	nginx.exe!ngx_http_core_types(ngx_conf_s * cf, ngx_command_s * cmd, void * conf) Line 3325	C
 	nginx.exe!ngx_conf_handler(ngx_conf_s * cf, int last) Line 429	C
 	nginx.exe!ngx_conf_parse(ngx_conf_s * cf, ngx_str_t * filename) Line 285	C
 	nginx.exe!ngx_conf_include(ngx_conf_s * cf, ngx_command_s * cmd, void * conf) Line 801	C
 	nginx.exe!ngx_conf_handler(ngx_conf_s * cf, int last) Line 429	C
 	nginx.exe!ngx_conf_parse(ngx_conf_s * cf, ngx_str_t * filename) Line 285	C
 	nginx.exe!ngx_http_block(ngx_conf_s * cf, ngx_command_s * cmd, void * conf) Line 237	C
 	nginx.exe!ngx_conf_handler(ngx_conf_s * cf, int last) Line 429	C
 	nginx.exe!ngx_conf_parse(ngx_conf_s * cf, ngx_str_t * filename) Line 285	C
 	nginx.exe!ngx_init_cycle(ngx_cycle_s * old_cycle) Line 274	C
 	nginx.exe!main(int argc, char * const * argv) Line 278	C

Memory Dump (first 4 bytes already was written):

0x00572F70  18 00 00 00 65 73 20 7b 0a 20 20 20 20 74 65 78 74 2f 68 74 6d 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ....es {.    text/html                          
0x00572FA0  20 20 20 68 74 6d 6c 20 68 74 6d 20 73 68 74 6d 6c 3b 0a 20 20 20 20 74 65 78 74 2f 63 73 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20     html htm shtml;.    text/css                 
0x00572FD0  20 20 20 20 20 20 20 20 20 20 20 20 20 63 73 73 3b 0a 20 20 20 20 74 65 78 74 2f 78 6d 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20               css;.    text/xml                  
0x00573000  20 20 20 20 20 20 20 20 20 20 20 20 78 6d 6c 3b 0a 20 20 20 20 69 6d 61 67 65 2f 67 69 66 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20              xml;.    image/gif                  
0x00573030  20 20 20 20 20 20 20 20 20 20 20 67 69 66 3b 0a 20 20 20 20 69 6d 61 67 65 2f 6a 70 65 67 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20             gif;.    image/jpeg                  

NOTE: after I add tracing of result for ngx_palloc fucnction and configure log.log_level to maximum in main() function i see that ngx_palloc in this moment really return same result as malloc early:

2016/06/11 17:03:44 [debug] 6512#18992: malloc: 00572F70:4096  //this is real buf allocation
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00571820
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00571860
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 005727E0
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572800
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572820
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572C40
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572C60
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572C80
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572CA0
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572CC0
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572CF0
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572D20
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572D40
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572D60
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572D80
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572DB0
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572DD0
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572DF0
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572E10
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572E30
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572E50
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572E70
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572E90
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572EB0
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572ED0
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572EF0
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572F20
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572F50
2016/06/11 17:03:44 [debug] 6512#18992: malloc: 00573F78:16384
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572F60
2016/06/11 17:03:44 [debug] 6512#18992: ngx_palloc result: 00572F70   //this is 'allocation' when we stay at memory breakpoint

5) Ok, continue execution and VS stay at our second breakpoint (at line if (cf->conf_file->buffer->start))
At this moment: cf->conf_file->buffer->start == 0x00572f70
And free() call fails (its look like that memory at 0x00572f70 already 'free'?)


Sorry for terrible english 8-(


UPD: version 1.9.12 build in this enviroment work ok with same config.

UPD (rus):
В целом похоже что где-то проблема толи с указателями в имплементации ngx_palloc_small, толи в двойном вызове free ....
На той же среде собранная в версия 1.9.12 работает ок

Change History (2)

comment:1 by Dmitry Afanasiev, 8 years ago

hmm... after remove --crossbuild=win32 and rebuild whith
uname -a equals MINGW32_NT-6.1-WOW WIN-AUJDDB361KN 2.4.0(0.292/5/3) 2016-01-07 19:11 i686 Msys nginx work as expected.

Sorry for issue, it can be closed 8-)

comment:2 by Valentin V. Bartenev, 8 years ago

Resolution: invalid
Status: newclosed
Note: See TracTickets for help on using tickets.