[CDRIVER-1209] _mongoc_cluster_auth_node_x509 segfault when failing to find username Created: 22/Apr/16  Updated: 10/Aug/16  Resolved: 09/May/16

Status: Closed
Project: C Driver
Component/s: auth
Affects Version/s: 1.4.0
Fix Version/s: 1.4.0

Type: Bug Priority: Major - P3
Reporter: Jeremy Mikola Assignee: Hannes Magnusson
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to PHPC-572 Ensure stream context does not go out... Closed
related to PHPC-677 Keep mongo_ssl_opt_t.pem_file valid f... Closed
related to CDRIVER-1316 Copy strings referred by mongoc_ssl_o... Closed

 Description   

The following tests in the PHPC project started crashing after upgrading to 1.4.0-dev:

The relevant PEM file is scripts/ssl/client.pem.

#0  strlen () at ../sysdeps/x86_64/strlen.S:106
No locals.
#1  0x00007f5cf9fe6bbd in _mongoc_cluster_auth_node_x509 (cluster=0x7f5cf86e8ef8, stream=0x7f5cf86df270, error=0x7f5cf86ea2a0)
    at /home/jmikola/workspace/mongodb/phpc/src/libmongoc/src/mongoc/mongoc-cluster.c:1026
        username = 0x0
        cmd = {flags = 3, len = 51, 
          padding = "3\000\000\000\020authenticate\000\001\000\000\000\002mechanism\000\r\000\000\000MONGODB-X509\000\000\t\375\177\000\000`<\273\t\375\177\000\000J\266\374\371\\\177\000\000\321\366\003\372\\\177\000\000\260<\273\t\375\177\000\000\220<\273\t\375\177\000\000\260<\273\t\375\177\000\000\220<\273\t\375\177\000\000*\272\374\371\\\177\000"}
        reply = {flags = 0, len = 0, 
          padding = "\260<\273\t\375\177\000\000\020=\273\t\375\177\000\000uw\001\372\\\177\000\000\000\000\000\000\000\000\000\000\260\227r\370\\\177\000\000`\230r\370\\\177\000\000?\000\000\000\004\000\000\000\004\000\000\000\005\000\000\000\023\000\000\000\027", '\000' <repeats 11 times>, "$", '\000' <repeats 38 times>}
        ret = false
        __func__ = "_mongoc_cluster_auth_node_x509"
#2  0x00007f5cf9fe74ca in _mongoc_cluster_auth_node (cluster=0x7f5cf86e8ef8, stream=0x7f5cf86df270, hostname=0x7f5cf86ea148 "192.168.112.10", max_wire_version=4, error=0x7f5cf86ea2a0)
    at /home/jmikola/workspace/mongodb/phpc/src/libmongoc/src/mongoc/mongoc-cluster.c:1214
        ret = false
        mechanism = 0x7f5cf8729877 "MONGODB-X509"
        __func__ = "_mongoc_cluster_auth_node"
#3  0x00007f5cf9fe8284 in mongoc_cluster_fetch_stream_single (cluster=0x7f5cf86e8ef8, sd=0x7f5cf86ea138, reconnect_ok=true, error=0x7ffd09bb4040)
    at /home/jmikola/workspace/mongodb/phpc/src/libmongoc/src/mongoc/mongoc-cluster.c:1617
        topology = 0x7f5cf87285b0
        stream = 0x7f5cf86df270
        scanner_node = 0x7f5cf87292b0
        expire_at = 140037308250016
        reply = {flags = 1459, len = 0, padding = "\230\350\003", '\000' <repeats 116 times>}
        __func__ = "mongoc_cluster_fetch_stream_single"
#4  0x00007f5cf9fe7cfa in _mongoc_cluster_stream_for_server_description (cluster=0x7f5cf86e8ef8, sd=0x7f5cf86ea138, reconnect_ok=true, error=0x7ffd09bb4040)
    at /home/jmikola/workspace/mongodb/phpc/src/libmongoc/src/mongoc/mongoc-cluster.c:1465
        topology = 0x7f5cf87285b0
        server_stream = 0x0
        __func__ = "_mongoc_cluster_stream_for_server_description"
#5  0x00007f5cf9fe8866 in _mongoc_cluster_stream_for_optype (cluster=0x7f5cf86e8ef8, optype=MONGOC_SS_WRITE, read_prefs=0x0, error=0x7ffd09bb4040)
    at /home/jmikola/workspace/mongodb/phpc/src/libmongoc/src/mongoc/mongoc-cluster.c:1805
        server_stream = 0x7ffd09bb4040
        selected_server = 0x7f5cf86ea138
        topology = 0x7f5cf87285b0
        __func__ = "_mongoc_cluster_stream_for_optype"
#6  0x00007f5cf9fe893a in mongoc_cluster_stream_for_writes (cluster=0x7f5cf86e8ef8, error=0x7ffd09bb4040) at /home/jmikola/workspace/mongodb/phpc/src/libmongoc/src/mongoc/mongoc-cluster.c:1867
No locals.
#7  0x00007f5cf9fde6df in mongoc_bulk_operation_execute (bulk=0x7f5cf86e9640, reply=0x7ffd09bb3fc0, error=0x7ffd09bb4040)
    at /home/jmikola/workspace/mongodb/phpc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c:430
        cluster = 0x7f5cf86e8ef8
        command = 0x2171e00
        server_stream = 0x216
        ret = false
        offset = 0
        i = 32604
        __func__ = "mongoc_bulk_operation_execute"
#8  0x00007f5cfa0283d0 in phongo_execute_write (client=0x7f5cf86e8ee8, namespace=0x7f5cf8727f38 "phongo.connect_standalone_x509_0002", bulk=0x7f5cf86e9640, write_concern=0x7f5cf86e9078, 
    server_id=-1, return_value=0x7f5cf8729238, return_value_used=0) at /home/jmikola/workspace/mongodb/phpc/php_phongo.c:540
        error = {domain = 1, code = 0, 
          message = "\000\000\000\000\000\000\000\000\250A\273\t\375\177\000\000\001<\326\375\\\177", '\000' <repeats 18 times>, "\001", '\000' <repeats 15 times>, "\001\000\000\000\000\000\000\000\000\036\027\002\000\000\000\000\001\000\000\000\000\000\000\000\000\036\027\002", '\000' <repeats 12 times>, "X!\027\002\000\000\000\000\360@\273\t\375\177\000\000X!\027\002\001\000\000\000\000\036\027\002\000\000\000\000\340@\273\t\375\177\000\000^\221\370\371\\\177\000\000Lr\001\327\000\000\000\000\377\377\377\377\000\000\000\000\060(X\312\000\000\000\000\030<\370\371\\\177\000\000\000\036\027\002\000\000\000\000\320/\370\371\\\177\000\000\000\036\027\002\000\000\000\000"...}
        dbname = 0x7f5cf86e8300 "ZZZZZZZZ\006C\221h"
        collname = 0x7f5cf86e8b08 "\001"
        success = 32765
        reply = {flags = 3, len = 5, padding = "\005", '\000' <repeats 118 times>}
        writeresult = 0x7ffd09bb4018
#9  0x00007f5cf9fad828 in zim_Manager_executeBulkWrite (ht=2, return_value=0x7f5cf8729238, return_value_ptr=0x7f5cfdf03570, this_ptr=0x7f5cf8727a38, return_value_used=0)
    at /home/jmikola/workspace/mongodb/phpc/src/MongoDB/Manager.c:155
        intern = 0x7f5cf8725c18
        namespace = 0x7f5cf8727f38 "phongo.connect_standalone_x509_0002"
        namespace_len = 35
        zbulk = 0x7f5cf86e7ee0
        zwrite_concern = 0x0
        bulk = 0x7f5cf871b5a8
#10 0x00000000008ccdab in zend_do_fcall_common_helper_SPEC (execute_data=0x7f5cfdf03a28) at /tmp/build_php-5.6.9.Ifh/php-5.6.9/Zend/zend_vm_execute.h:558
        ret = 0x7f5cfdf03568
        opline = 0x7f5cf86d8ca0
        should_change_scope = 1 '\001'
        fbc = 0x22c4470
        num_args = 2
#11 0x00000000008cd57f in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0x7f5cfdf03a28) at /tmp/build_php-5.6.9.Ifh/php-5.6.9/Zend/zend_vm_execute.h:693
No locals.
#12 0x00000000008cc414 in execute_ex (execute_data=0x7f5cfdf03a28) at /tmp/build_php-5.6.9.Ifh/php-5.6.9/Zend/zend_vm_execute.h:363
        ret = 0
        original_in_execution = 0 '\000'
#13 0x00000000008cc49d in zend_execute (op_array=0x7f5cfdf3e220) at /tmp/build_php-5.6.9.Ifh/php-5.6.9/Zend/zend_vm_execute.h:388
No locals.
#14 0x00000000008858d1 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /tmp/build_php-5.6.9.Ifh/php-5.6.9/Zend/zend.c:1341
        __orig_bailout = 0x7ffd09bb69b0
        __bailout = {{__jmpbuf = {0, -5617334378191232983, 4356928, 140724766735568, 0, 0, -5617334377041993687, 5616318239940304937}, __mask_was_saved = 0, __saved_mask = {__val = {34663632, 
                253552, 140037374095689, 140724766725872, 8692391, 0, 8555574853632, 14002984, 140037374095688, 140724766730048, 9156438, 140724766730880, 34661440, 0, 322122547200, 
                140037374095688}}}}
        prepend_file_p = 0x0
        append_file_p = 0x0
        prepend_file = {type = ZEND_HANDLE_FILENAME, filename = 0x0, opened_path = 0x0, handle = {fd = 0, fp = 0x0, stream = {handle = 0x0, isatty = 0, mmap = {len = 0, pos = 0, map = 0x0, 
                buf = 0x0, old_handle = 0x0, old_closer = 0x0}, reader = 0x0, fsizer = 0x0, closer = 0x0}}, free_filename = 0 '\000'}
        append_file = {type = ZEND_HANDLE_FILENAME, filename = 0x0, opened_path = 0x0, handle = {fd = 0, fp = 0x0, stream = {handle = 0x0, isatty = 0, mmap = {len = 0, pos = 0, map = 0x0, 
                buf = 0x0, old_handle = 0x0, old_closer = 0x0}, reader = 0x0, fsizer = 0x0, closer = 0x0}}, free_filename = 0 '\000'}
        old_cwd = 0x7ffd09bb4500 ""
        use_heap = 0 '\000'
        retval = 0
#16 0x0000000000940cc8 in do_cli (argc=66, argv=0x210d950) at /tmp/build_php-5.6.9.Ifh/php-5.6.9/sapi/cli/php_cli.c:994
        __orig_bailout = 0x7ffd09bb7b20
        __bailout = {{__jmpbuf = {0, -5617334378103152599, 4356928, 140724766735568, 0, 0, -5617334378189135831, 5616316921597550633}, __mask_was_saved = 0, __saved_mask = {__val = {
                140037303128064, 140724766730704, 140724766731144, 12884901892, 35073232, 140037307566231, 6, 140037374599520, 140037348660481, 2049, 1316002, 1, 33261, 0, 0, 0}}}}
        c = -1
        file_handle = {type = ZEND_HANDLE_MAPPED, filename = 0x210e440 "/home/jmikola/workspace/mongodb/phpc/tests/connect/standalone-x509-0002.php", opened_path = 0x0, handle = {
            fd = -34348136, fp = 0x7f5cfdf3e398, stream = {handle = 0x7f5cfdf3e398, isatty = 0, mmap = {len = 1774, pos = 0, map = 0x7f5cfdf78000, 
                buf = 0x7f5cfdf78000 <error: Cannot access memory at address 0x7f5cfdf78000>, old_handle = 0x22e38f0, old_closer = 0x8a5e83 <zend_stream_stdio_closer>}, 
              reader = 0x8a5e54 <zend_stream_stdio_reader>, fsizer = 0x8a5eb4 <zend_stream_stdio_fsizer>, closer = 0x8a5fee <zend_stream_mmap_closer>}}, free_filename = 0 '\000'}
        behavior = 1
        reflection_what = 0x0
        request_started = 1
        exit_status = 0
        php_optarg = 0x210e440 "/home/jmikola/workspace/mongodb/phpc/tests/connect/standalone-x509-0002.php"
        orig_optarg = 0x0
        php_optind = 66
        orig_optind = 1
        exec_direct = 0x0
        exec_run = 0x0
        exec_begin = 0x0
        exec_end = 0x0
        arg_free = 0x210e440 "/home/jmikola/workspace/mongodb/phpc/tests/connect/standalone-x509-0002.php"
        arg_excp = 0x210db58
        script_file = 0x210e440 "/home/jmikola/workspace/mongodb/phpc/tests/connect/standalone-x509-0002.php"
        translated_path = 0x22e3e70 "/home/jmikola/workspace/mongodb/phpc/tests/connect/standalone-x509-0002.php"
        interactive = 0
        lineno = 1
        param_error = 0x0
        hide_argv = 0
#17 0x0000000000941ff0 in main (argc=66, argv=0x210d950) at /tmp/build_php-5.6.9.Ifh/php-5.6.9/sapi/cli/php_cli.c:1378
        __orig_bailout = 0x0
        __bailout = {{__jmpbuf = {0, -5617334378075889623, 4356928, 140724766735568, 0, 0, -5617334378101055447, 5616316922008723497}, __mask_was_saved = 0, __saved_mask = {__val = {
                140037348165344, 5, 66, 140724766735576, 140037372444448, 140037318717704, 66, 140724766735576, 140037372444448, 1, 9758349, 4356928, 0, 9758272, 4356928, 140724766735568}}}}
        c = -1
        exit_status = 0
        module_started = 1
        sapi_started = 1
        php_optarg = 0x210e440 "/home/jmikola/workspace/mongodb/phpc/tests/connect/standalone-x509-0002.php"
        php_optind = 66
        use_extended_info = 0
        ini_path_override = 0x210e4a0 "/home/jmikola/workspace/mongodb/phpc/tmp-php.ini"
        ini_entries = 0x210e900 "html_errors=0\nregister_argc_argv=1\nimplicit_flush=1\noutput_buffering=0\nmax_execution_time=0\nmax_input_time=-1\noutput_handler=\nopen_basedir=\nsafe_mode=0\ndisable_functions=\noutput_buffering=Off\nerror_re"...
        ini_entries_len = 737
        ini_ignore = 1
        sapi_module = 0x1074240 <cli_sapi_module>

Relevant PHP info:

mongodb
 
mongodb support => enabled
mongodb version => 1.2.0-dev
mongodb stability => devel
libmongoc version => 1.4.0-dev
libbson version => 1.4.0-dev
 
Directive => Local Value => Master Value
mongodb.debug => no value => no value
 
openssl
 
OpenSSL support => enabled
OpenSSL Library Version => OpenSSL 1.0.1f 6 Jan 2014
OpenSSL Header Version => OpenSSL 1.0.1f 6 Jan 2014
 
Directive => Local Value => Master Value
openssl.cafile => no value => no value
openssl.capath => no value => no value



 Comments   
Comment by Githook User [ 27/Apr/16 ]

Author:

{u'username': u'bjori', u'name': u'Hannes Magnusson', u'email': u'bjori@php.net'}

Message: CDRIVER-1209: segfault when failing to find username
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/575288df3ad220a9a8f55f90413e8043723ebd79

Comment by Hannes Magnusson [ 22/Apr/16 ]

Actually, no, it can't.

_mongoc_openssl_setup_pem_file () would fail long before we get to that code path. Maybe if the file was removed in between? o.O

Comment by Hannes Magnusson [ 22/Apr/16 ]

Probably yes. We shouldn't be doing this at all though.
The user is explicitly expected to provide the username per the auth docs.

I guess you are right though, passing any random file as pem_file would probably hit this problem

Comment by Jeremy Mikola [ 22/Apr/16 ]

bjori: I understand that PHPC was at fault here for not keeping the pem_file string allocated, but isn't there still an issue with __mongoc_cluster_auth_node_x509() segfaulting if mongoc_ssl_extract_subject() fails to resolve a username?

Looking at the OpenSSL implementation in _mongoc_openssl_extract_subject(), the return value will remain NULL if PEM_read_bio_X509(), X509_get_subject_name(), or X509_NAME_print_ex() return unsuccessfully.

I think you would want a defensive check if username remains unset after the following block in _mongoc_cluster_auth_node_x509():

if (cluster->client->ssl_opts.pem_file) {
   username = mongoc_ssl_extract_subject (cluster->client->ssl_opts.pem_file,
                                          cluster->client->ssl_opts.pem_pwd);
   MONGOC_INFO ("X509: got username (%s) from certificate", username);
}

Comment by Hannes Magnusson [ 22/Apr/16 ]

http://api.mongodb.org/c/current/mongoc_client_set_ssl_opts.html

Although the mongoc_ssl_opt_t struct itself is shallow-copied by the client, the strings it points to (pem_file, pem_pwd, ca_file, ca_dir, and crl_file) are not copied and must remain valid for the life of the mongoc_client_t.

Generated at Wed Feb 07 21:11:53 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.