test failure with current master in Fedora build environment #136
Comments
Can you post the exact steps you used to compile http-parser? Please start with a |
Here's a detailed backtrace that shows how it overflows a buffer in header_value_cb(): #0 0x00000030bcc35935 in raise () from /lib64/libc.so.6 No symbol table info available. #1 0x00000030bcc370e8 in abort () from /lib64/libc.so.6 No symbol table info available. #2 0x00000030bcc74e8b in __libc_message () from /lib64/libc.so.6 No symbol table info available. #3 0x00000030bcd094d7 in __fortify_fail () from /lib64/libc.so.6 No symbol table info available. #4 0x00000030bcd07690 in __chk_fail () from /lib64/libc.so.6 No symbol table info available. #5 0x00000030bcd06823 in __strncat_chk () from /lib64/libc.so.6 No symbol table info available. #6 0x0000000000401d9d in strncat (__len=, __src=, __dest=) at /usr/include/bits/string3.h:152 No locals. #7 header_value_cb (p=, buf=, len=) at ../../../../../personal/tmp/rpm/BUILD/joyent-http-parser-245f6f0/test.c:1446 m = 0x6f29e0 #8 0x00007ffff7dfa8dc in http_parser_execute (parser=0x706010, settings=settings@entry=0x6f2840, data=data@entry=0x404b50 "GET / HTTP/1.1\r\nX-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n\tAk"..., len=2044) at ../../../../../personal/tmp/rpm/BUILD/joyent-http-parser-245f6f0/http_parser.c:1425 c = ch = unhex_val = p = 0x404da5 "\r\n\tgW7cMA/s/XKgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL\r\n\t0iwHDdNkGjy5pyBSB8Y79dsSJtCW/iaLB0/n8Sj7HgvvZJ7x0fr+RQjYOUUfrePP\r\n\tu2MSpFyf+9BbC/aXgaZuiCvSR+8Snv3xApQY+fULK/xY8h8Ua51iXoQ5jrgu2Sq"... header_field_mark = 0x0 header_value_mark = 0x404d65 "W51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YR\r\n\tgW7cMA/s/XKgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL\r\n\t0iwHDdNkGjy5pyBSB8Y79dsSJtCW/iaLB0/n8Sj7HgvvZJ7x0fr+RQjYOUUfrePP\r\n"... url_mark = 0x0 body_mark = #9 0x0000000000402227 in parse ( buf=buf@entry=0x404b50 "GET / HTTP/1.1\r\nX-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n\tAk"..., len=) at ../../../../../personal/tmp/rpm/BUILD/joyent-http-parser-245f6f0/test.c:1737 No locals. #10 0x00000000004033b2 in test_simple ( buf=buf@entry=0x404b50 "GET / HTTP/1.1\r\nX-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n\tAk"..., err_expected=err_expected@entry=HPE_OK) at ../../../../../personal/tmp/rpm/BUILD/joyent-http-parser-245f6f0/test.c:2659 err = #11 0x0000000000401450 in main () at ../../../../../personal/tmp/rpm/BUILD/joyent-http-parser-245f6f0/test.c:3241 i = 20 j = k = request_count = 34 response_count = 20 all_methods = {0x407cfb "DELETE", 0x407d02 "GET", 0x407d06 "HEAD", 0x407d0b "POST", 0x407d10 "PUT", 0x407d14 "OPTIONS", 0x407d1c "TRACE", 0x407d22 "COPY", 0x407d47 "LOCK", 0x407d27 "MKCOL", 0x407d2d "MOVE", 0x407d32 "PROPFIND", 0x407d3b "PROPPATCH", 0x407d45 "UNLOCK", 0x407d4c "REPORT", 0x407d53 "MKACTIVITY", 0x407d5e "CHECKOUT", 0x407d67 "MERGE", 0x407d6d "M-SEARCH", 0x407d76 "NOTIFY", 0x407d7f "SUBSCRIBE", 0x407d7d "UNSUBSCRIBE", 0x407d3f "PATCH", 0x0} this_method = bad_methods = {0x407d89 "C******", 0x407d91 "M****", 0x0} dumbfuck2 = 0x404b50 "GET / HTTP/1.1\r\nX-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n\tAk"... |
@mschwendt Do you have a test case I can try? |
The src.rpm that was built can be found here: http://koji.fedoraproject.org/koji/buildinfo?buildID=369508 It includes everything you need, but the %check section to run the test-suite is commented out in the spec file and would need to be uncommented. I simply built the package on Fedora 17 x86_64 to verify that the issue is not specific to the Fedora buildsystem. |
The RPM does a few more elaborate things like addiitonal arch-specific CFLAGS and it builds a shared library, but the above is sufficient to reproduce this locally. |
A deeper albeit quick look in the debugger, in test.c strlen(dumbfuck2) is 2044, headers MAX_ELEMENT_SIZE is only 500, however, and it overflows those 500 by appending chunks of the full 2044 characters via strncat. Even if it's just test.c, this is inherently insecure coding style, if the "n" in strncat is not set appropriately to avoid a buffer overflow. It should always recalculate the remaining "n" relative to the buffer dest ptr. |
Can you guys verify if 32 bits build have the same issue? I can't reproduce it on a 32 bits F18 install. Valgrind doesn't complain either. |
Well, I can confirm that CentOS 6 i686 isn't affected (no 32-bit Fedora installation here anymore for quick access). rpmbuild excerpt: + cd joyent-http-parser-245f6f0 + unset DISPLAY + export LD_LIBRARY_PATH=./out/Release/lib.target + LD_LIBRARY_PATH=./out/Release/lib.target + ./out/Release/test-nonstrict sizeof(http_parser) = 28 response scan 1/2 100% response scan 2/2 100% responses okay request scan 1/4 100% request scan 2/4 100% request scan 3/4 100% request scan 4/4 100% requests okay + ./out/Release/test-strict sizeof(http_parser) = 28 response scan 1/2 100% response scan 2/2 100% responses okay request scan 1/4 100% request scan 2/4 100% request scan 3/4 100% request scan 4/4 100% requests okay + exit 0 That's unusual, because that could mean you may have managed to make something arch-dependent in the C code, perhaps with unsafe casts or sizeof assumptions. FORTIFY_SOURCE isn't anything like a new feature. Do you have any comment on what I've pointed out further above? Simply increasing MAX_ELEMENT_SIZE to something larger than strlen(dumbfuck2) makes the tests succeed on F17 x86_64 without causing a buffer overflow. Could you think of anything to enhance the test suite in any related way? |
Inserting some printf lines in header_value_cb(), I see that the 32-bit build also overflows the buffer, but this isn't caught by strncat protection. The diff between 64-bit and 32-bit debug output is as follows. The lines prefixed with "+" are printed only for the 32-bit build: @@ -1,4 +1,4 @@ -sizeof(http_parser) = 32 +sizeof(http_parser) = 28 headers = len = 22 strlen(header) = 22 @@ -16669273,3 +16669273,4698291 @@ strlen(header) = 475 headers = -----BEGIN CERTIFICATE-----MIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQ AwcDELMAkGA1UEBhMCVUsxETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBg NVBAMTAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswHhcNMD YwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNjaWVuY2 UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNVBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWV sIHBhcmQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R6 4fAcEF len = 64 +strlen(header) = 539 +headers = -----BEGIN CERTIFICATE-----MIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQ AwcDELMAkGA1UEBhMCVUsxETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBg NVBAMTAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswHhcNMD YwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNjaWVuY2 UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNVBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWV sIHBhcmQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R6 4fAcEFW51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YR +len = 64 +strlen(header) = 603 +headers = -----BEGIN CERTIFICATE-----MIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQ AwcDELMAkGA1UEBhMCVUsxETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBg NVBAMTAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswHhcNMD YwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNjaWVuY2 UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNVBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWV sIHBhcmQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R6 4fAcEFW51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YRgW7cMA/s/X KgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL +len = 64 +strlen(header) = 667 ... ... and so on for 32-bit, whereas 64-bit has crashed at the top of this diff already. |
I'm getting the folowing failure in
test-nonstrict
with the latest master in the Fedora build environment:Judging by the backtrace I'd guess this has something to do with the Fedora buildsystem adding
-D_FORTIFY_SOURCE=2
to CFLAGS. I'm not sure whether this can be fixed on your end or we'll have to remove that from CFLAGS. (The full build output from the buildsystem is here if that's helpful.)The text was updated successfully, but these errors were encountered: