Created attachment 16397 [details] Patch to check if tdb->mutex is NULL before munmap() We're running 4.9.18, 4.10.18, and 4.11.17 on Solaris 10/SPARC and 11/SPARC and are seeing a SEGV when running smbstatus. In lib/tdb/common/open.c, we have: _PUBLIC_ int tdb_close(struct tdb_context *tdb) { ... tdb_mutex_munmap(tdb); SAFE_FREE(tdb->name); ... } And in lib/tdb/common/mutex.c, we have: int tdb_mutex_munmap(struct tdb_context *tdb) { ... ret = munmap(tdb->mutexes, len); if (ret == -1) { return -1; } ... } Should tdb->mutexes be non-NULL? I looked at the value on both Solaris and RHEL 6 and tdb->mutexes is NULL at this point. Before munmap(), we have: (dbx) print *tdb *tdb = { name = 0x355d8 "/var/opt/TWWfsw/samba4918/lock/locking.tdb", map_ptr = (nil), fd = 11, map_size = 90112U, read_only = 1, traverse_read = 0, traverse_write = 0, allrecord_lock = { off = 0, count = 0, ltype = 0 }, num_lockrecs = 0, lockrecs = (nil), lockrecs_array_length = 0, hdr_ofs = 245760U, mutexes = (nil), ecode = TDB_SUCCESS, hash_size = 10007U, feature_flags = 1U, flags = 2596U, travlocks = { next = (nil), off = 0, list = 0, lock_rw = 0 }, next = 0x47d00, device = 74776595U, inode = 5617ULL, log = { log_fn = 0xfd120cc0 = &`libtdb-wrap-samba4.so`tdb_wrap.c`tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, const char *format, void *..., ...), log_private = (nil) }, hash_fn = 0xfee575b8 = &tdb_jenkins_hash(), open_flags = 0, methods = 0xfee70fcc, transaction = (nil), page_size = 8192, max_dead_records = 0, interrupt_sig_ptr = (nil) } On RHEL, I see the following: (gdb) print *tdb $2 = {name = 0x55555577d600 "/var/opt/TWWfsw/samba4918/lock/locking.tdb", map_ptr = 0x0, fd = 14, map_size = 86016, read_only = 1, traverse_read = 0, traverse_write = 0, allrecord_lock = {off = 0, count = 0, ltype = 0}, num_lockrecs = 0, lockrecs = 0x0, lockrecs_array_length = 0, hdr_ofs = 401408, mutexes = 0x0, ecode = TDB_SUCCESS, hash_size = 10007, feature_flags = 1, flags = 2564, travlocks = {next = 0x0, off = 0, list = 0, lock_rw = 0}, next = 0x55555577d6c0, device = 64768, inode = 3153808, log = {log_fn = 0x7ffff236adbc <tdb_wrap_log>, log_private = 0x0}, hash_fn = 0x7ffff21603da <tdb_jenkins_hash>, open_flags = 0, methods = 0x7ffff2368ae0, transaction = 0x0, page_size = 4096, max_dead_records = 0, interrupt_sig_ptr = 0x0} After munmap(), we have: (dbx) print *tdb *tdb = { name = 0x355d8 "<bad address 0x000355d8>", map_ptr = (nil), fd = 11, map_size = 90112U, read_only = 1, traverse_read = 0, traverse_write = 0, allrecord_lock = { off = 0, count = 0, ltype = 0 }, num_lockrecs = 0, lockrecs = (nil), lockrecs_array_length = 0, hdr_ofs = 245760U, mutexes = (nil), ecode = TDB_SUCCESS, hash_size = 10007U, feature_flags = 1U, flags = 2596U, travlocks = { next = (nil), off = 0, list = 0, lock_rw = 0 }, next = 0x47d00, device = 74776595U, inode = 5617ULL, log = { log_fn = 0xfd120cc0 = &`libtdb-wrap-samba4.so`tdb_wrap.c`tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, const char *format, void *..., ...), log_private = (nil) }, hash_fn = 0xfee575b8 = &tdb_jenkins_hash(), open_flags = 0, methods = 0xfee70fcc, transaction = (nil), page_size = 8192, max_dead_records = 0, interrupt_sig_ptr = (nil) } (gdb) print *tdb $3 = {name = 0x55555577d600 "/var/opt/TWWfsw/samba4918/lock/locking.tdb", map_ptr = 0x0, fd = 14, map_size = 86016, read_only = 1, traverse_read = 0, traverse_write = 0, allrecord_lock = {off = 0, count = 0, ltype = 0}, num_lockrecs = 0, lockrecs = 0x0, lockrecs_array_length = 0, hdr_ofs = 401408, mutexes = 0x0, ecode = TDB_SUCCESS, hash_size = 10007, feature_flags = 1, flags = 2564, travlocks = {next = 0x0, off = 0, list = 0, lock_rw = 0}, next = 0x55555577d6c0, device = 64768, inode = 3153808, log = {log_fn = 0x7ffff236adbc <tdb_wrap_log>, log_private = 0x0}, hash_fn = 0x7ffff21603da <tdb_jenkins_hash>, open_flags = 0, methods = 0x7ffff2368ae0, transaction = 0x0, page_size = 4096, max_dead_records = 0, interrupt_sig_ptr = 0x0} On Solaris, the differences are: -*tdb = { name = 0x355d8 "/var/opt/TWWfsw/samba4918/lock/locking.tdb", +*tdb = { name = 0x355d8 "<bad address 0x000355d8>", From munmap(2) on Solaris: The munmap() function removes the mappings for pages in the range [addr, addr + len), rounding the len argument up to the next multiple of the page size as returned by sysconf(3C). If addr is not the address of a mapping established by a prior call to mmap(2), the behavior is undefined. After a successful call to munmap() and before any subse- quent mapping of the unmapped pages, further references to these pages will result in the delivery of a SIGBUS or SIGSEGV signal to the process.