Bug 14882 - smbXsrv_client_global record validation leads to crash if existing record points at non-existing process
Summary: smbXsrv_client_global record validation leads to crash if existing record poi...
Status: RESOLVED FIXED
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: File services (show other bugs)
Version: unspecified
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Jule Anger
QA Contact: Samba QA Contact
URL:
Keywords:
: 14849 (view as bug list)
Depends on:
Blocks:
 
Reported: 2021-10-26 08:29 UTC by Ralph Böhme
Modified: 2021-11-18 17:10 UTC (History)
4 users (show)

See Also:


Attachments
git-am fix for 4.15.next. (7.57 KB, patch)
2021-11-04 20:19 UTC, Jeremy Allison
slow: review+
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ralph Böhme 2021-10-26 08:29:23 UTC
SBT:

#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50	../sysdeps/unix/sysv/linux/raise.c: Datei oder Verzeichnis nicht gefunden.
(gdb) (gdb) #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
        set = {__val = {6272, 0, 0, 0, 0, 0, 0, 94450030750608, 
            140085527315220, 335544320, 140085522011952, 32, 94450030750708, 
            0, 0, 0}}
        pid = <optimized out>
        tid = <optimized out>
        ret = <optimized out>
#1  0x00007f6833ac0535 in __GI_abort () at abort.c:79
        save_stage = 1
        act = {__sigaction_handler = {sa_handler = 0x55e6dc882bf4, 
            sa_sigaction = 0x55e6dc882bf4}, sa_mask = {__val = {0, 0, 0, 0, 0, 
              17179869184, 8356462415537375488, 140085526804288, 
              140725831436240, 140085451467160, 10, 94450030648800, 
              140085526780402, 3472608676021285467, 335544320, 
              140085522011952}}, sa_flags = -519960320, sa_restorer = 0x0}
        sigs = {__val = {32, 0 <repeats 15 times>}}
#2  0x00007f683409178e in dump_core () at ../../source3/lib/dumpcore.c:338
        called = true
        __FUNCTION__ = "dump_core"
#3  0x00007f683409fcd8 in smb_panic_s3 (why=<optimized out>)
    at ../../source3/lib/util.c:704
        lp_sub = <optimized out>
        cmd = <optimized out>
        result = <optimized out>
        __FUNCTION__ = "smb_panic_s3"
#4  0x00007f6834180302 in smb_panic (
    why=why@entry=0x7f68339fe458 "assert failed: rec->value_valid")
    at ../../lib/util/fault.c:197
No locals.
#5  0x00007f68339f9941 in dbwrap_record_get_value (rec=<optimized out>)
    at ../../lib/dbwrap/dbwrap.c:82
        __FUNCTION__ = "dbwrap_record_get_value"
#6  0x00007f683435b44c in smbXsrv_client_global_store (global=0x55e6dc876a00)
    at ../../source3/smbd/smbXsrv_client.c:367
        global_blob = {version = (unknown: 3699906908), seqnum = 21990, 
          info = {info0 = 0xb1, dummy = 0xb1}}
        key = {
          dptr = 0x55e6dc881948 "%\365%\246r\031Q\263\210\375,Ϥ\347\332v", 
          dsize = 16}
        val = <optimized out>
        status = <optimized out>
        blob = {data = 0x0, length = 0}
        ndr_err = <optimized out>
        saved_stored = false
        global_blob = <optimized out>
        blob = <optimized out>
        key = <optimized out>
        val = <optimized out>
        status = <optimized out>
        ndr_err = <optimized out>
        saved_stored = <optimized out>
        __FUNCTION__ = "smbXsrv_client_global_store"
        __func__ = "smbXsrv_client_global_store"
#7  smb2srv_client_mc_negprot_next (req=req@entry=0x55e6dc824fa0)
    at ../../source3/smbd/smbXsrv_client.c:497
        state = <optimized out>
        xconn = 0x55e6dc875320
        client = 0x55e6dc83d600
        table = <optimized out>
        client_guid = {time_low = 2787505445, time_mid = 6514, 
          time_hi_and_version = 45905, 
          clock_seq = "\210", <incomplete sequence \375>, 
          node = ",Ϥ\347\332v"}
        global = 0x0
        is_free = true
        subreq = 0x0
        status = <optimized out>
        __FUNCTION__ = "smb2srv_client_mc_negprot_next"
        __func__ = "smb2srv_client_mc_negprot_next"
#8  0x00007f683435ce1d in smb2srv_client_mc_negprot_send (
    mem_ctx=mem_ctx@entry=0x55e6dc883100, ev=0x55e6dc827b20, 
    smb2req=smb2req@entry=0x55e6dc86eed0)
    at ../../source3/smbd/smbXsrv_client.c:451
        req = 0x55e6dc824fa0
        state = 0x55e6dc825160
#9  0x00007f6834343058 in smbd_smb2_request_process_negprot (
    req=req@entry=0x55e6dc86eed0) at ../../source3/smbd/smb2_negprot.c:801
        state = 0x55e6dc883100
        xconn = 0x55e6dc875320
        subreq = 0x0
        status = <optimized out>
        inbody = <optimized out>
        indyn = <optimized out>
        outbody = <optimized out>
        outdyn = {
          data = 0x55e6dc83c590 "`^\006\006+\006\001\005\005\002\240T0R\240$0\"\006\t*\206H\202\367\022\001\002\002\006\t*\206H\206\367\022\001\002\002\006\n+\006\001\004\001\202\067\002\002\n\243*0(\240&\033$not_defined_in_RFC4178@please_ignore", length = 96}
        negprot_spnego_blob = <optimized out>
        security_offset = 128
        security_buffer = <optimized out>
        expected_dyn_size = 8
        c = <optimized out>
        security_mode = 3
        dialect_count = 4
        in_security_mode = 1
        in_capabilities = <optimized out>
        in_guid_blob = {
          data = 0x55e6dc83c7ec "%\365%\246r\031Q\263\210\375,Ϥ\347\332v", 
          length = 16}
        in_guid = {time_low = 2787505445, time_mid = 6514, 
          time_hi_and_version = 45905, 
          clock_seq = "\210", <incomplete sequence \375>, 
          node = ",Ϥ\347\332v"}
        in_c = {num_contexts = 0, contexts = 0x0}
        in_preauth = <optimized out>
        in_cipher = <optimized out>
        in_sign_algo = <optimized out>
        out_c = {num_contexts = 0, contexts = 0x0}
        default_smb3_capabilities = {signing = {num_algos = 3, algos = {2, 1, 
              0}}, encryption = {num_algos = 4, algos = {2, 1, 4, 3}}}
        out_negotiate_context_blob = {data = 0x0, length = 0}
        out_negotiate_context_offset = 0
        out_negotiate_context_count = 0
        dialect = 770
        capabilities = 71
        out_guid_blob = {data = 0x55e6dc83c580 "lxfilhamdev39", length = 16}
        out_guid = {time_low = 1768323180, time_mid = 26732, 
          time_hi_and_version = 28001, clock_seq = "de", node = "v39\000\000"}
        protocol = <optimized out>
        max_limit = <optimized out>
        max_trans = 8388608
        max_read = 8388608
        max_write = 8388608
        now = 132796440399001200
        signing_required = <optimized out>
        ok = <optimized out>
        __FUNCTION__ = "smbd_smb2_request_process_negprot"
#10 0x00007f683433e38c in smbd_smb2_request_dispatch (
    req=req@entry=0x55e6dc86eed0) at ../../source3/smbd/smb2_server.c:3360
        xconn = <optimized out>
        call = <optimized out>
        intf_v = <optimized out>
        inhdr = <optimized out>
        opcode = 0
        flags = <optimized out>
        mid = <optimized out>
        status = {v = 0}
        session_status = <optimized out>
        allowed_flags = <optimized out>
        return_value = <optimized out>
        x = 0x0
        signing_required = false
        encryption_desired = <optimized out>
        encryption_required = false
        __FUNCTION__ = "smbd_smb2_request_dispatch"
#11 0x00007f6834340487 in smbd_smb2_io_handler (fde_flags=<optimized out>, 
    xconn=0x55e6dc875320) at ../../source3/smbd/smb2_server.c:5003
        err = <optimized out>
        sconn = 0x55e6dc8508b0
        state = 0x55e6dc875420
        req = 0x55e6dc86eed0
        min_recvfile_size = <optimized out>
        ret = <optimized out>
        retry = false
        status = {v = 0}
        msg = {msg_name = 0x0, msg_namelen = 0, msg_iov = 0x55e6dc875430, 
          msg_iovlen = 1, msg_control = 0x0, msg_controllen = 0, msg_flags = 0}
        now = <optimized out>
        sconn = <optimized out>
        state = <optimized out>
        req = <optimized out>
        min_recvfile_size = <optimized out>
        ret = <optimized out>
        err = <optimized out>
        retry = <optimized out>
        status = <optimized out>
        now = <optimized out>
        msg = <optimized out>
        __FUNCTION__ = "smbd_smb2_io_handler"
        base = <optimized out>

The problem is that in smbXsrv_client_global_verify_record() we delete the record if we find one that points at a non-existing process. This causes record->value_valid to be set to false.

Subsequently we continue to use the record which leads to the crash when calling dbwrap_record_get_value().

ML candidate: https://lists.samba.org/archive/samba-technical/2020-April/135116.html
Comment 1 Jeremy Allison 2021-10-26 21:34:22 UTC
Yep, 100% spot-on analysis. Question is, how to fix ? I'm assuming once smbXsrv_client_global_verify_record() returns is_free=true and has called dbwrap_record_delete() we need to drop the record and recreate and re-acquire the lock ?

Can you explain the ideas you have for fixing this. I'm eager to learn as this is an area I don't understand well enough :-(.
Comment 2 Samba QA Contact 2021-11-04 19:50:04 UTC
This bug was referenced in samba master:

c1470b120bb75ea73ba90dc83ab7efcbb733b1a7
1fa006f1f71cce03d92e76efda3ff055aae4eb91
8082e2eb7e33c0993135791c03823886f5aa8496
Comment 3 Jeremy Allison 2021-11-04 20:19:46 UTC
Created attachment 16957 [details]
git-am fix for 4.15.next.

Cherry-picked from master.
Comment 4 Ralph Böhme 2021-11-05 08:51:30 UTC
Reassigning for inclusion in 4.15.
Comment 5 Jule Anger 2021-11-10 14:32:50 UTC
Pushed to autobuild-v4-15-test.
Comment 6 Samba QA Contact 2021-11-10 17:08:40 UTC
This bug was referenced in samba v4-15-test:

a16283466ba0985441e7bc084e8477f47e8d2e60
8bb5f0911a8504bb8e4c89282c43d651b690fa78
3a34628266f8df1513092ec8bdf0c391b6afc7c4
Comment 7 Jule Anger 2021-11-10 18:03:57 UTC
Closing out bug report.

Thanks!
Comment 8 Björn Jacke 2021-11-18 17:10:35 UTC
*** Bug 14849 has been marked as a duplicate of this bug. ***