[PATCH] Perl: NULL-terminate argument list
Piotr Sikora
piotr at cloudflare.com
Tue Aug 5 10:33:18 UTC 2014
Hey Maxim,
> Somebody have to investigate these crashes to find out where the
> problem is. As previously suggested, nginx code matches perlembed
> samples, and it looks like as either perl itself or perlembed bug.
> I also suspect that the patch fixes things due to some
> side effect, not because it does something needed.
>
> If you have no plans to investigate it yourself, you may want to
> share a way to reproduce the problem.
I did enough of investigation to be satisfied with the patch I
provided and I have no plans to dig into perl's code, especially
because I have no interest in the perl module itself.
Like I said, this condition can be triggered when using malloc with
guard pages, when argv[argc] == pool->d.last == pool->d.end.
For me, it's 100% reproducible when running nginx-tests under OSX's
guard malloc against fully built nginx built:
$ ./objs/nginx -V
nginx version: nginx/1.7.4 (f8764e20fcd7)
built by clang 3.4.2 (tags/RELEASE_34/dot2-final)
TLS SNI support enabled
configure arguments: --build=f8764e20fcd7 --with-debug
--with-http_ssl_module --with-http_spdy_module --with-debug
--with-ipv6 --with-http_ssl_module --with-http_spdy_module
--with-http_realip_module --with-http_addition_module
--with-http_xslt_module --with-http_image_filter_module
--with-http_geoip_module --with-http_sub_module --with-http_dav_module
--with-http_flv_module --with-http_mp4_module
--with-http_gunzip_module --with-http_gzip_static_module
--with-http_auth_request_module --with-http_random_index_module
--with-http_secure_link_module --with-http_stub_status_module
--with-http_perl_module --with-mail --with-mail_ssl_module
--with-cc-opt='-O0 -ggdb'
$ env MALLOC_FILL_SPACE=1 MALLOC_STRICT_SIZE=1
DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib prove auth_basic.t
http_server_name.t
auth_basic.t ........ Can't start nginx at lib/Test/Nginx.pm line 227.
# Looks like your test exited with 2 before it could output anything.
auth_basic.t ........ Dubious, test returned 2 (wstat 512, 0x200)
Failed 19/19 subtests
http_server_name.t .. Can't start nginx at lib/Test/Nginx.pm line 227.
# Looks like your test exited with 2 before it could output anything.
http_server_name.t .. Dubious, test returned 2 (wstat 512, 0x200)
Failed 9/9 subtests
Test Summary Report
-------------------
auth_basic.t (Wstat: 512 Tests: 0 Failed: 0)
Non-zero exit status: 2
Parse errors: Bad plan. You planned 19 tests but ran 0.
http_server_name.t (Wstat: 512 Tests: 0 Failed: 0)
Non-zero exit status: 2
Parse errors: Bad plan. You planned 9 tests but ran 0.
Files=2, Tests=0, 4 wallclock secs ( 0.11 usr 0.44 sys + 0.76 cusr
2.39 csys = 3.70 CPU)
Result: FAIL
$ lldb objs/nginx
Current executable set to 'objs/nginx' (x86_64).
(lldb) env MALLOC_FILL_SPACE=1
(lldb) env MALLOC_STRICT_SIZE=1
(lldb) env DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib
(lldb) r
Process 48754 launched: 'objs/nginx' (x86_64)
Process 48754 stopped
* thread #1: tid = 0xa7e9a, 0x00000001006c1aaf
libperl.dylib`perl_parse + 4148, queue = 'com.apple.main-thread', stop
reason = EXC_BAD_ACCESS (code=1, address=0x103279000)
frame #0: 0x00000001006c1aaf libperl.dylib`perl_parse + 4148
libperl.dylib`perl_parse + 4148:
-> 0x1006c1aaf: movq (%rax), %rcx
0x1006c1ab2: movq %rcx, -0x960(%rbp)
0x1006c1ab9: cmpq $0x0, 0x4f8(%r12)
0x1006c1ac2: movl -0x924(%rbp), %r14d
(lldb) bt
* thread #1: tid = 0xa7e9a, 0x00000001006c1aaf
libperl.dylib`perl_parse + 4148, queue = 'com.apple.main-thread', stop
reason = EXC_BAD_ACCESS (code=1, address=0x103279000)
* frame #0: 0x00000001006c1aaf libperl.dylib`perl_parse + 4148
frame #1: 0x0000000100101b77
nginx`ngx_http_perl_create_interpreter(cf=0x00007fff5fbff4b0,
pmcf=0x00000001030821c8) + 775 at ngx_http_perl_module.c:599
frame #2: 0x000000010010143a
nginx`ngx_http_perl_init_interpreter(cf=0x00007fff5fbff4b0,
pmcf=0x00000001030821c8) + 298 at ngx_http_perl_module.c:520
frame #3: 0x0000000100102846
nginx`ngx_http_perl_init_main_conf(cf=0x00007fff5fbff4b0,
conf=0x00000001030821c8) + 54 at ngx_http_perl_module.c:813
frame #4: 0x00000001000534e6
nginx`ngx_http_block(cf=0x00007fff5fbff4b0, cmd=0x0000000100142cc0,
conf=0x000000010307ff28) + 1462 at ngx_http.c:264
frame #5: 0x0000000100022d8c
nginx`ngx_conf_handler(cf=0x00007fff5fbff4b0, last=1) + 1068 at
ngx_conf_file.c:391
frame #6: 0x0000000100021899
nginx`ngx_conf_parse(cf=0x00007fff5fbff4b0,
filename=0x000000010307f1d0) + 1065 at ngx_conf_file.c:247
frame #7: 0x000000010001db5f
nginx`ngx_init_cycle(old_cycle=0x00007fff5fbff5a8) + 2719 at
ngx_cycle.c:264
frame #8: 0x0000000100000e6e nginx`main(argc=5,
argv=0x00007fff5fbff7d0) + 766 at nginx.c:333
(lldb) f 1
frame #1: 0x0000000100101b77
nginx`ngx_http_perl_create_interpreter(cf=0x00007fff5fbff4b0,
pmcf=0x00000001030821c8) + 775 at ngx_http_perl_module.c:599
596 embedding[n++] = "-e";
597 embedding[n++] = "0";
598
-> 599 n = perl_parse(perl, ngx_http_perl_xs_init, n, embedding, NULL);
600
601 if (n != 0) {
602 ngx_log_error(NGX_LOG_ALERT, cf->log, 0, "perl_parse()
failed: %d", n);
(lldb) p n
(int) $0 = 4
(lldb) p embedding[0]
(char *) $1 = 0x000000010012f43c ""
(lldb) p embedding[1]
(char *) $2 = 0x000000010013c0a4 "-Mnginx"
(lldb) p embedding[2]
(char *) $3 = 0x000000010013c0ac "-e"
(lldb) p embedding[3]
(char *) $4 = 0x000000010013c0af "0"
(lldb) p embedding[4]
error: Couldn't apply expression side effects : Couldn't dematerialize
a result variable: couldn't read its memory
(lldb) p &embedding[0]
(char **) $6 = 0x0000000103278fe0
(lldb) p &embedding[1]
(char **) $7 = 0x0000000103278fe8
(lldb) p &embedding[2]
(char **) $8 = 0x0000000103278ff0
(lldb) p &embedding[3]
(char **) $9 = 0x0000000103278ff8
(lldb) p &embedding[4]
(char **) $10 = 0x0000000103279000
As you can see, embedding[4] is the address which triggered
EXC_BAD_ACCESS, so perl_parse() must have tried to access it.
Let me know if I can be of further assistance.
Best regards,
Piotr Sikora
More information about the nginx-devel
mailing list