We upgraded from 4.3.11 to 4.6.4 and during the next business day we started seeing panics. Here is the logs/backtrace: [2017/09/08 09:33:16.001228, 0, pid=24759] ../source3/lib/util.c:791(smb_panic_s3) PANIC (pid 24759): getwd failed [2017/09/08 09:33:16.001683, 0, pid=24759] ../source3/lib/util.c:902(log_stack_trace) BACKTRACE: 26 stack frames: #0 /usr/pkg/lib/libsmbconf.so.0'log_stack_trace+0x2d [0xfdfdb6cd] #1 /usr/pkg/lib/libsmbconf.so.0'smb_panic_s3+0x2b [0xfdfdb7fb] #2 /usr/pkg/lib/libsamba-util.so.0.0.1'smb_panic+0x36 [0xfedac546] #3 /usr/pkg/lib/samba/vfs/shadow_copy2.so'shadow_copy2_chdir+0x377 [0xfb87ad67] #4 /usr/pkg/lib/samba/private/libsmbd-base-samba4.so'smb_vfs_call_chdir+0x33 [0xfe51bad3] #5 /usr/pkg/lib/samba/private/libsmbd-base-samba4.so'vfs_ChDir+0x5e [0xfe51cc6e] #6 /usr/pkg/lib/samba/private/libsmbd-base-samba4.so'open_dir_safely+0x40 [0xfe4ae0a0] #7 /usr/pkg/lib/samba/private/libsmbd-base-samba4.so'get_real_filename_full_scan+0xe2 [0xfe503b82] #8 /usr/pkg/lib/samba/private/libsmbd-base-samba4.so'unix_convert+0xad4 [0xfe504c44] #9 /usr/pkg/lib/samba/private/libsmbd-base-samba4.so'filename_convert_internal+0xfc [0xfe505d9c] #10 /usr/pkg/lib/samba/private/libsmbd-base-samba4.so'filename_convert+0x46 [0xfe5060f6] #11 /usr/pkg/lib/samba/private/libsmbd-base-samba4.so'smbd_smb2_request_process_create+0x244c [0xfe551cbc] #12 /usr/pkg/lib/samba/private/libsmbd-base-samba4.so'smbd_smb2_request_dispatch+0x1074 [0xfe546ac4] #13 /usr/pkg/lib/samba/private/libsmbd-base-samba4.so'smbd_smb2_connection_handler+0x6bf [0xfe54786f] #14 /usr/pkg/lib/samba/private/libtevent.so.0.9.31'port_event_loop_once+0x2de [0xfe7cb22e] #15 /usr/pkg/lib/samba/private/libtevent.so.0.9.31'_tevent_loop_once+0xa3 [0xfe7c50d3] #16 /usr/pkg/lib/samba/private/libtevent.so.0.9.31'tevent_common_loop_wait+0x2c [0xfe7c52fc] #17 /usr/pkg/lib/samba/private/libtevent.so.0.9.31'_tevent_loop_wait+0x18 [0xfe7c5398] #18 /usr/pkg/lib/samba/private/libsmbd-base-samba4.so'smbd_process+0x855 [0xfe533955] #19 /usr/pkg/sbin/smbd'smbd_accept_connection+0x281 [0x805c491] #20 /usr/pkg/lib/samba/private/libtevent.so.0.9.31'port_event_loop_once+0x2de [0xfe7cb22e] #21 /usr/pkg/lib/samba/private/libtevent.so.0.9.31'_tevent_loop_once+0xa3 [0xfe7c50d3] #22 /usr/pkg/lib/samba/private/libtevent.so.0.9.31'tevent_common_loop_wait+0x2c [0xfe7c52fc] #23 /usr/pkg/lib/samba/private/libtevent.so.0.9.31'_tevent_loop_wait+0x18 [0xfe7c5398] #24 /usr/pkg/sbin/smbd'main+0x1a5f [0x805f35f] #25 /usr/pkg/sbin/smbd'_start+0x83 [0x8056653] The error string and backtrace point to this line: https://github.com/samba-team/samba/blob/v4-6-stable/source3/modules/vfs_shadow_copy2.c#L1516 It appears the changes to the shadow_copy2 module have introduced an easily triggered smb_panic by having a hard dependency on GETWD. In our environment, GETWD uses getcwd(3), which generates the working directory by traversing up parent directories and reading their names. Since traversing into directories only requires search and not read, this panic can be reliably triggered if the share has any search-only directories with readable subdirectories and shadow_copy2 enabled. Our current workaround is to disable shadow_copy2.
I would consider this a serious security bug. Basically any authenticated user with write access to a share with shadow copy enabled can set the permissions on a directory to trigger this panic and crash the server, resulting in a DoS.
Not a serious security bug, sorry. It's a DOS but from an authenticated user, yes. The getwd() fix is a necessary one for security race conditions so that can't be reverted. What environment are you using where "In our environment, GETWD uses getcwd(3)" ? No modern Linux or FreeBSD does this to my knowledge.
Well, yes, it would definitely be worse if it was an unauthenticated DoS; perhaps I'd call that critical ;). But still, I'd saying having any random user able to DoS your service, particularly in an environment where you don't necessarily trust your random users (educational institution, students 8-/), is pretty serious. We're running samba under OmniOS, which is a distribution of illumos, the fork of OpenSolaris from when Oracle shut it down. I'm assuming commercial Solaris would have the same issue but have not verified it.
Any chance you can move off to Linux / FreeBSD ? Depending on Solaris is not a good long term solution... https://twitter.com/webmink/status/904081073256243201
We're not depending on Solaris; as I said we're running OmniOS, an illumos distribution: https://wiki.illumos.org/display/illumos/illumos+Home While illumos is a fork of OpenSolaris, it has zero dependencies on commercial Solaris or Oracle, and the death of either is irrelevant to its use or viability (Oh, if only Oracle would die, if only, if only). There are a number of otyher widely used open source illumos based distributions such as OpenIndiana or SmartOS, as well as commercial products based on it such as Nexenta or Delphix. It's not going anywhere.
Can you get me a backtrace with symbols. I'll take a look, but we're not going to be able to remove the GETWD code, it is a vital security requirement. It's possible the best we can do is note that shadow_copy2 is incompatible with Solaris-based systems.
My colleague will follow up on the backtrace. Can you at least make it fail in a way that doesn't crash the entire service? I haven't had a chance to look at the code in detail myself yet, but is there any way if the getwd fails to just make shadow copies not work/fail on that share for that user as opposed to killing off the entire process? It seems a bit excessive for a security check for one user on one share to completely remove access to all shares for all users when it fails.
It depends. When I see the full backtrace I'll know. It panics as it thinks someone is trying to symlink race the server, which we must not allow.
Reproduced with smbclient by connecting and doing the following steps, where the first "New folder" has read permission removed: smb: \> cd "New folder" smb: \New folder\> cd "New folder" smb: \New folder\New folder\> ls NT_STATUS_IO_TIMEOUT listing \New folder\New folder\* gdb bt full after breaking on smb_panic: #0 smb_panic (why=why@entry=0xfb84f279 "getwd failed\n") at ../lib/util/fault.c:164 No locals. #1 0xfb84ad67 in store_cwd_data (connectpath=0x0, handle=0x80b1010) at ../source3/modules/vfs_shadow_copy2.c:1516 priv = 0x80b0eb0 cwd = 0x0 #2 shadow_copy2_chdir (handle=0x80b1010, fname=<optimized out>) at ../source3/modules/vfs_shadow_copy2.c:1574 timestamp = 0 stripped = 0x0 snappath = 0x0 ret = 0 saved_errno = 0 conv = 0x0 rootpath_len = 0 #3 0xfe51bad3 in smb_vfs_call_chdir (handle=<optimized out>, path=path@entry=0x80b6e60 "New folder/New folder") at ../source3/smbd/vfs.c:2099 No locals. #4 0xfe51cc6e in vfs_ChDir (conn=conn@entry=0x80b1fc8, path=0x80b6e60 "New folder/New folder") at ../source3/smbd/vfs.c:876 ret = <optimized out> __FUNCTION__ = "vfs_ChDir" #5 0xfe4ae0a0 in open_dir_safely (ctx=0x0, conn=0x80b1fc8, smb_dname=0x80b6dc0, wcard=0x80b6c00 "*", attr=22) at ../source3/smbd/dir.c:1689 dir_hnd = 0x0 smb_fname_cwd = 0x0 saved_dir = 0x80b02e0 "/export/user/bldewolf" #6 0xfe4af577 in OpenDir (mem_ctx=<optimized out>, mem_ctx@entry=0x0, conn=<optimized out>, conn@entry=0x80b1fc8, smb_dname=<optimized out>, smb_dname@entry=0x80b6dc0, mask=mask@entry=0x80b6c00 "*", attr=attr@entry=22) at ../source3/smbd/dir.c:1744 No locals. #7 0xfe4b0219 in dptr_create (conn=0x80b1fc8, req=req@entry=0x80b6750, fsp=fsp@entry=0x0, smb_dname=0x80b68d0, old_handle=old_handle@entry=false, expect_close=expect_close@entry=true, spid=5746, wcard=0x80b6c00 "*", wcard_has_wild=true, attr=22, dptr_ret=dptr_ret@entry=0x80472b8) at ../source3/smbd/dir.c:533 ret = <optimized out> backup_intent = <optimized out> status = <optimized out> smb_dname_cp = 0x80b6dc0 sconn = 0x80a3170 dptr = 0x0 dir_hnd = <optimized out> __FUNCTION__ = "dptr_create" #8 0xfe4ef31d in call_trans2findfirst (conn=conn@entry=0x80b1fc8, req=req@entry=0x80b6750, pparams=pparams@entry=0x80b01c4, total_params=62, ppdata=ppdata@entry=0x80b01cc, total_data=0, max_data_bytes=65535) at ../source3/smbd/trans2.c:2815 params = <optimized out> pdata = 0x80b9cf0 "" data_end = <optimized out> dirtype = <optimized out> maxentries = <optimized out> findfirst_flags = <optimized out> close_after_first = <optimized out> close_if_end = <optimized out> requires_resume_key = <optimized out> info_level = <optimized out> directory = 0x80b6970 "New folder/New folder" mask = <optimized out> p = 0x80b6985 "" last_entry_off = 0 dptr_num = -1 numentries = 0 i = <optimized out> finished = false dont_descend = false out_of_space = false space_remaining = <optimized out> mask_contains_wcard = true ea_list = <optimized out> ntstatus = {v = 0} ask_sharemode = <optimized out> dirptr = 0x0 sconn = <optimized out> ucf_flags = <optimized out> backup_priv = <optimized out> as_root = <optimized out> __FUNCTION__ = "call_trans2findfirst" #9 0xfe4fb236 in handle_trans2 (conn=conn@entry=0x80b1fc8, req=req@entry=0x80b6750, state=state@entry=0x80b0180) at ../source3/smbd/trans2.c:9334 __FUNCTION__ = "handle_trans2" #10 0xfe4ff1b6 in reply_trans2 (req=0x80b6750) at ../source3/smbd/trans2.c:9620 conn = 0x80b1fc8 dsoff = 132 dscnt = <optimized out> psoff = 68 pscnt = 62 tran_call = <optimized out> state = 0x80b0180 result = <optimized out> __FUNCTION__ = "reply_trans2" #11 0xfe52e58d in switch_message (type=<optimized out>, req=req@entry=0x80b6750) at ../source3/smbd/process.c:1726 flags = <optimized out> session_tag = <optimized out> conn = <optimized out> xconn = <optimized out> now = <optimized out> session = 0x809ae20 status = <optimized out> __FUNCTION__ = "switch_message" #12 0xfe5306ca in construct_reply (deferred_pcd=0x0, encrypted=false, seqnum=0, unread_bytes=0, size=136, inbuf=0x0, xconn=0x809be58) at ../source3/smbd/process.c:1762 sconn = <optimized out> req = 0x80b6750 #13 process_smb (xconn=xconn@entry=0x809be58, inbuf=<optimized out>, nread=136, unread_bytes=0, seqnum=0, encrypted=false, deferred_pcd=deferred_pcd@entry=0x0) at ../source3/smbd/process.c:2008 sconn = 0x80a3170 msg_type = <optimized out> __FUNCTION__ = "process_smb" #14 0xfe532223 in smbd_server_connection_read_handler (xconn=0x809be58, fd=<optimized out>) at ../source3/smbd/process.c:2608 inbuf = 0x80b6690 "" inbuf_len = 136 unread_bytes = 0 encrypted = false mem_ctx = 0x80b6660 status = {v = 0} seqnum = 0 async_echo = <optimized out> from_client = <optimized out> __FUNCTION__ = "smbd_server_connection_read_handler" #15 0xfe7cb22e in port_event_loop (tvalp=0x8047650, port_ev=0x80963c0) at ../lib/tevent/tevent_port.c:603 mpx_fde = <optimized out> fde = <optimized out> flags = <optimized out> val = <optimized out> ret = <optimized out> nget = 1 max_events = 1 i = 0 port_errno = <optimized out> events = {{portev_events = 1, portev_source = 4, portev_pad = 0, portev_object = 10, portev_user = 0x80a6190}} ts = {tv_sec = 42, tv_nsec = 290369000} ev = 0x8096318 #16 port_event_loop_once (ev=0x8096318, location=0xfe6b68ec "../source3/smbd/process.c:4125") at ../lib/tevent/tevent_port.c:781 port_ev = 0x80963c0 tval = {tv_sec = 42, tv_usec = 290369} #17 0xfe7c50d3 in _tevent_loop_once (ev=ev@entry=0x8096318, location=location@entry=0xfe6b68ec "../source3/smbd/process.c:4125") at ../lib/tevent/tevent.c:721 ret = <optimized out> nesting_stack_ptr = 0x0 #18 0xfe7c52fc in tevent_common_loop_wait (ev=0x8096318, location=0xfe6b68ec "../source3/smbd/process.c:4125") at ../lib/tevent/tevent.c:844 ret = <optimized out> #19 0xfe7c5398 in _tevent_loop_wait (ev=0x8096318, location=location@entry=0xfe6b68ec "../source3/smbd/process.c:4125") at ../lib/tevent/tevent.c:863 No locals. #20 0xfe533955 in smbd_process (ev_ctx=ev_ctx@entry=0x8096318, msg_ctx=msg_ctx@entry=0x8098448, sock_fd=sock_fd@entry=10, interactive=interactive@entry=false) at ../source3/smbd/process.c:4125 trace_state = {ev = 0x8096318, frame = 0x80b6660} client = 0x80a2ab0 sconn = 0x80a3170 xconn = 0x809be58 locaddr = <optimized out> remaddr = <optimized out> ret = <optimized out> status = <optimized out> tv = {tv_sec = 1505246493, tv_usec = 194018} now = <optimized out> chroot_dir = <optimized out> rc = <optimized out> __func__ = "smbd_process" __FUNCTION__ = "smbd_process" #21 0x0805c491 in smbd_accept_connection (ev=0x8096318, fde=0x80a5ad0, flags=1, private_data=0x80a3220) at ../source3/smbd/server.c:1017 status = {v = 0} s = 0x0 msg_ctx = 0x8098448 addr = {ss_family = 26, _ss_pad1 = "\347\200\000\000\000", _ss_align = 1.4583677777643215e-302, _ss_pad2 = "\000\000\000\002\356\356\356\356\000\000\000\000\000\000\000\000\000\000g\374\004\bg\374@1\n\bhx\004\b\000\000\000\000\004\bg\374.\200Y\374\253\070\204\376\000\000g\374\004\bg\374@1\n\b\210x\004\b\213\201Y\374\004\bg\374\000\000\000\000\310x\004\b\330l`\374\004\bg\374\000\000\000\000\000\000\000\000n(\204\376@1\n\b\250\223\t\b\004\bg\374\re`\374\004\bg\374\000\000\000\000\by\004\b\371\234|\376\020y\004\b|\352\t\b\330x\004\b\000\000\000\000\004\bg\374\000\000\000\000\333\234|\376\\\311}\376p\352\t\b\020y\004\b8y\004\b5\243|\376\030y\004\b\020y\004\b|\352\t\b\000\000\000\000\004\bg\374"...} in_addrlen = 32 fd = 10 pid = <optimized out> __FUNCTION__ = "smbd_accept_connection" #22 0xfe7cb22e in port_event_loop (tvalp=0x8047980, port_ev=0x80963c0) at ../lib/tevent/tevent_port.c:603 mpx_fde = <optimized out> fde = <optimized out> flags = <optimized out> val = <optimized out> ret = <optimized out> nget = 1 max_events = 1 i = 0 port_errno = <optimized out> events = {{portev_events = 1, portev_source = 4, portev_pad = 0, portev_object = 37, portev_user = 0x80a6848}} ts = {tv_sec = 746, tv_nsec = 335205000} ev = 0x8096318 #23 port_event_loop_once (ev=0x8096318, location=0x8062ec9 "../source3/smbd/server.c:1384") at ../lib/tevent/tevent_port.c:781 port_ev = 0x80963c0 tval = {tv_sec = 746, tv_usec = 335205} #24 0xfe7c50d3 in _tevent_loop_once (ev=ev@entry=0x8096318, location=location@entry=0x8062ec9 "../source3/smbd/server.c:1384") at ../lib/tevent/tevent.c:721 ret = <optimized out> nesting_stack_ptr = 0x0 #25 0xfe7c52fc in tevent_common_loop_wait (ev=0x8096318, location=0x8062ec9 "../source3/smbd/server.c:1384") at ../lib/tevent/tevent.c:844 ret = <optimized out> #26 0xfe7c5398 in _tevent_loop_wait (ev=0x8096318, location=location@entry=0x8062ec9 "../source3/smbd/server.c:1384") at ../lib/tevent/tevent.c:863 No locals. #27 0x0805f35f in smbd_parent_loop (parent=<optimized out>, ev_ctx=<optimized out>) at ../source3/smbd/server.c:1384 trace_state = {frame = 0x80a5b40} ret = 0 #28 main (argc=<optimized out>, argv=0x8047de0) at ../source3/smbd/server.c:2038 is_daemon = <optimized out> interactive = <optimized out> Fork = <optimized out> no_process_group = <optimized out> log_stdout = <optimized out> ports = 0x0 profile_level = 0x0 opt = <optimized out> pc = <optimized out> print_build_options = <optimized out> main_server_id = {pid = 5833, task_id = 0, vnn = 4294967295, unique_id = 3380973686010842310} long_options = {{longName = 0x0, shortName = 0 '\000', argInfo = 4, arg = 0xfc759b60 <poptHelpOptions>, val = 0, descrip = 0x8063474 "Help options:", argDescrip = 0x0}, {longName = 0x8063482 "daemon", shortName = 68 'D', argInfo = 0, arg = 0x0, val = 1000, descrip = 0x8063489 "Become a daemon (default)", argDescrip = 0x0}, {longName = 0x80634a3 "interactive", shortName = 105 'i', argInfo = 0, arg = 0x0, val = 1001, descrip = 0x80614d0 "Run interactive (not a daemon)", argDescrip = 0x0}, {longName = 0x80634af "foreground", shortName = 70 'F', argInfo = 0, arg = 0x0, val = 1002, descrip = 0x80614f0 "Run daemon in foreground (for daemontools, etc.)", argDescrip = 0x0}, {longName = 0x80634ba "no-process-group", shortName = 0 '\000', argInfo = 0, arg = 0x0, val = 1003, descrip = 0x8061524 "Don't create a new process group", argDescrip = 0x0}, {longName = 0x80634cb "log-stdout", shortName = 83 'S', argInfo = 0, arg = 0x0, val = 1004, descrip = 0x80634d6 "Log to stdout", argDescrip = 0x0}, { longName = 0x80634e4 "build-options", shortName = 98 'b', argInfo = 0, arg = 0x0, val = 98, descrip = 0x80634f2 "Print build options", argDescrip = 0x0}, {longName = 0x8063506 "port", shortName = 112 'p', argInfo = 1, arg = 0x8047b04, val = 0, descrip = 0x806350b "Listen on the specified ports", argDescrip = 0x0}, {longName = 0x8063529 "profiling-level", shortName = 80 'P', argInfo = 1, arg = 0x8047b08, val = 0, descrip = 0x8063539 "Set profiling level", argDescrip = 0x806354d "PROFILE_LEVEL"}, {longName = 0x0, shortName = 0 '\000', argInfo = 4, arg = 0xfee238a0 <popt_common_samba>, val = 0, descrip = 0x806355b "Common samba options:", argDescrip = 0x0}, {longName = 0x0, shortName = 0 '\000', argInfo = 0, arg = 0x0, val = 0, descrip = 0x0, argDescrip = 0x0}} parent = <optimized out> frame = <optimized out> status = <optimized out> ev_ctx = <optimized out> msg_ctx = <optimized out> server_id = {pid = 5834, task_id = 0, vnn = 4294967295, unique_id = 8775075741836112969} se = <optimized out> profiling_level = <optimized out> np_dir = <optimized out> smbd_shim_fns = {cancel_pending_lock_requests_by_fid = 0x805651c <smbd_cancel_pending_lock_requests_by_fid@plt>, send_stat_cache_delete_message = 0x805652c <smbd_send_stat_cache_delete_message@plt>, change_to_root_user = 0x805653c <smbd_change_to_root_user@plt>, become_authenticated_pipe_user = 0x805654c <smbd_become_authenticated_pipe_user@plt>, unbecome_authenticated_pipe_user = 0x805655c <smbd_unbecome_authenticated_pipe_user@plt>, contend_level2_oplocks_begin = 0x805656c <smbd_contend_level2_oplocks_begin@plt>, contend_level2_oplocks_end = 0x805657c <smbd_contend_level2_oplocks_end@plt>, become_root = 0x805658c <smbd_become_root@plt>, unbecome_root = 0x805659c <smbd_unbecome_root@plt>, exit_server = 0x80565ac <smbd_exit_server@plt>, exit_server_cleanly = 0x80565bc <smbd_exit_server_cleanly@plt>} __FUNCTION__ = "main"
It's failing inside store_cwd_data(), which is only called from shadow_copy2_chdir() after the SMB_VFS_NEXT_CHDIR() has succeeded. The only thing I can think of is doing a local patch that passes in the argument passed to SMB_VFS_NEXT_CHDIR(), and if the getwd() fails it uses that as the directory returned from GETWD(). This is inherently insecure though, and can't go upstream. Can you give this a go and see if it fixes your problem ?
I'm certainly not advocating anything be done insecurely. In this scenario, I have no issue with service being denied if the getwd fails. However, stepping back a moment, do you really agree with the design philosophy that if the getwd call fails for one user trying to access one share, the proper failure mode is to panic the entire samba server, killing off the parent process and all children, denying service to all users on all existing connections and any future users attempting to connect to any shares? There's no way for this to fail securely and either simply not allow shadow copies to work for this user on this share, or even just not allow this user to access this share at all, rather than going nuclear on the entire process? If shadow copies are simply not enabled, the share works fine (and presumably securely) in this state, so denying access to shadow copies (rather than denying access to the whole share, let alone the whole server) when this condition arises would seem to maintain security without compromising availability? Thanks...
The issue is the lower level shadow_copy2 code doesn't know what the upper level is doing. All it knows is a directory that it just chdir()'ed into is not resolvable with getwd(). That usually means shenanigans, so terminating is a fail safe here. Samba is full of areas where: chdir("....path....") getwd() => error is an immediate panic. If getwd() fails chdir should also fail.
Created attachment 13594 [details] git-am fix for master You know what. I think I was wrong in my previous comment. Can you test the following patch ? It may fix the issue for you. Cheers, Jeremy.
I backported the patch to 4.6.4 and tested it out. The server no longer panics, but things still get weird when looking at a broken perms nested directory. If I try to create a file, it fails with bad permissions and starts returning access denied for the entire share until the server is restarted. So I have three test cases currently: 4.6.4 patched with shadow_copy2: gives perm denied in test dir then starts denying entire share 4.6.4 no shadow_copy2: gives perm denied but still works outside bad perms test dir 4.3.11 with shadow_copy2: allows file creation/etc in the bad perms test dir While fiddling with this, I wanted to see if the cwd of the samba process was getting mangled and found "pwdx". I poked at "pwdx" and realized it readlink's /proc/self/path/cwd, which made me a bit annoyed that getcwd is unwilling to give out information readily available from proc. So I made a quick LD_PRELOAD library that emulates getcwd and getwd by reading proc. Running with this lib makes the 4.6.4 patched with shadow_copy2 testcase no longer deny permission to everything after being poked, so I suspect there's still some dependency on working getcwd/getwd lurking somewhere. I'd also like to squish the regression of not being able to do file operations in a directory with an unreadable parent, but that looks like it might not be caused by broken getcwd/getwd operations. I'll see if I can find some more time to poke at this more.
Yes, the patch isn't correct yet. It will leave us in the wrong directory. I realized that this morning in the shower. I'll fix this and upload a new version.
Created attachment 13601 [details] Updated git-am patch for master. Here's the update. Can you test ? Thanks ! Jeremy.
Sorry for the delay on this one. I was having trouble getting a build with your latest patch going but I tried again with 4.7.0 and got it. Viewing the folder shows its contents, but when I try to create a file in the folder I get this panic trace: #0 0xfc5a1d85 in _lwp_kill () from /lib/libc.so.1 No symbol table info available. #1 0xfc599422 in thr_kill () from /lib/libc.so.1 No symbol table info available. #2 0xfc53672b in raise () from /lib/libc.so.1 No symbol table info available. #3 0xfc51104e in abort () from /lib/libc.so.1 No symbol table info available. #4 0xfdfcd7ef in dump_core () at ../source3/lib/dumpcore.c:338 called = true __FUNCTION__ = "dump_core" #5 0xfdfbbf24 in smb_panic_s3 (why=0xfb78fe57 "talloc failed\n") at ../source3/lib/util.c:827 cmd = <optimized out> result = <optimized out> __FUNCTION__ = "smb_panic_s3" #6 0xfed9cde6 in smb_panic (why=why@entry=0xfb78fe57 "talloc failed\n") at ../lib/util/fault.c:166 No locals. #7 0xfb78b1d6 in store_cwd_data (connectpath=0x0, handle=0x80b2568) at ../source3/modules/vfs_shadow_copy2.c:1546 priv = 0x80b25c0 cwd_fname = 0x0 #8 shadow_copy2_chdir (handle=0x80b2568, smb_fname=0x80bbf20) at ../source3/modules/vfs_shadow_copy2.c:1625 timestamp = 0 stripped = 0x0 snappath = 0x0 ret = 0 saved_errno = 0 conv = 0x0 rootpath_len = 0 conv_smb_fname = 0x80bc400 saved_cwd_fname = 0x80bc570 #9 0xfe597bc3 in smb_vfs_call_chdir (handle=<optimized out>, smb_fname=smb_fname@entry=0x80bbf20) at ../source3/smbd/vfs.c:2141 No locals. #10 0xfe598c10 in vfs_ChDir (conn=conn@entry=0x809b6f0, smb_fname=smb_fname@entry=0x80bbf20) at ../source3/smbd/vfs.c:877 ret = <optimized out> __FUNCTION__ = "vfs_ChDir" #11 0xfe529e4e in open_dir_safely (ctx=0x80bbee0, conn=0x809b6f0, smb_dname=0x80bbf20, wcard=0x0, attr=0) at ../source3/smbd/dir.c:1690 dir_hnd = 0x0 smb_fname_cwd = 0x0 saved_dir_fname = 0x80bc230 #12 0xfe52b327 in OpenDir (mem_ctx=<optimized out>, conn=<optimized out>, conn@entry=0x809b6f0, smb_dname=<optimized out>, smb_dname@entry=0x80bbf20, mask=mask@entry=0x0, attr=attr@entry=0) at ../source3/smbd/dir.c:1745 No locals. #13 0xfe57f992 in get_real_filename_full_scan (conn=0x809b6f0, path=0x80bbe50 "New folder/New folder", path@entry=0x813445af <error: Cannot access memory at address 0x813445af>, name=0x80a8976 "New Text Document.txt", mangled=false, mem_ctx=0x80bbee0, found_name=0x80470cc) at ../source3/smbd/filename.c:1381 cur_dir = <optimized out> dname = 0x0 talloced = <optimized out> unmangled_name = <optimized out> curpos = 134908278 smb_fname = 0x80bbf20 __FUNCTION__ = "get_real_filename_full_scan" #14 0xfe57ff83 in get_real_filename (conn=0x80a8976, conn@entry=0x809b6f0, path=0x0, name=0x80bbee0 "\340\277\v\b\002", mem_ctx=0x80470cc, found_name=found_name@entry=0x80470cc) at ../source3/smbd/filename.c:1465 ret = <optimized out> mangled = <optimized out> #15 0xfe580aa4 in unix_convert (ctx=0x80c3248, conn=conn@entry=0x809b6f0, orig_path=0x80b08e8 "New folder/New folder/New Text Document.txt", smb_fname_out=0x804739c, ucf_flags=ucf_flags@entry=32) at ../source3/smbd/filename.c:920 found_name = 0x0 smb_fname = 0x80ae120 cnull = 0 '\000' start = 0x80a8976 "New Text Document.txt" end = 0x0 stream = 0x0 component_was_mangled = false name_has_wildcard = false posix_pathnames = false allow_wcard_last_component = false save_last_component = false snapshot_path = false status = <optimized out> ret = <optimized out> __FUNCTION__ = "unix_convert" #16 0xfe581c29 in filename_convert_internal (ctx=ctx@entry=0x80c3248, conn=conn@entry=0x809b6f0, smbreq=smbreq@entry=0x0, name_in=<optimized out>, name_in@entry=0x80b08e8 "New folder/New folder/New Text Document.txt", ucf_flags=ucf_flags@entry=32, ppath_contains_wcard=ppath_contains_wcard@entry=0x0, pp_smb_fname=pp_smb_fname@entry=0x804739c) at ../source3/smbd/filename.c:1619 status = <optimized out> __FUNCTION__ = "filename_convert_internal" #17 0xfe581f9e in filename_convert (ctx=0x80c3248, conn=0x809b6f0, name_in=0x80b08e8 "New folder/New folder/New Text Document.txt", ucf_flags=32, ppath_contains_wcard=ppath_contains_wcard@entry=0x0, pp_smb_fname=pp_smb_fname@entry=0x804739c) at ../source3/smbd/filename.c:1664 No locals. #18 0xfe5ce0c8 in smbd_smb2_create_send (in_context_blobs=..., in_name=<optimized out>, in_create_options=<optimized out>, in_create_disposition=<optimized out>, in_share_access=<optimized out>, in_file_attributes=<optimized out>, in_desired_access=<optimized out>, in_impersonation_level=<optimized out>, in_oplock_level=<optimized out>, smb2req=<optimized out>, ev=<optimized out>, mem_ctx=<optimized out>) at ../source3/smbd/smb2_create.c:1114 smb_fname = 0x0 ucf_flags = <optimized out> ea_list = <optimized out> sec_desc = <optimized out> durable_requested = <optimized out> need_replay_cache = <optimized out> mxac = <optimized out> max_access_time = <optimized out> allocation_size = <optimized out> lease_ptr = <optimized out> lease_len = <optimized out> op = 0x0 fname = <optimized out> secd = <optimized out> _create_guid = {time_low = 1045307681, time_mid = 40099, time_hi_and_version = 4583, clock_seq = "\200\335", node = "\000PV\215Fd"} create_guid = <optimized out> do_durable_reconnect = <optimized out> persistent_id = <optimized out> exta = <optimized out> qfid = <optimized out> update_open = <optimized out> lease = {lease_key = {data = {18446673710247975600, 3954}}, lease_state = 7, lease_flags = 0, lease_duration = 0, parent_lease_key = {data = {0, 0}}, lease_version = 2, lease_epoch = 0} alsi = <optimized out> twrp = <optimized out> durable_timeout_msec = <optimized out> state = 0x80c3328 smb1req = <optimized out> req = <optimized out> result = 0x0 dhnc = <optimized out> dh2c = <optimized out> status = <optimized out> info = 0 requested_oplock_level = <optimized out> rqls = <optimized out> dhnq = <optimized out> dh2q = <optimized out> replay_operation = <optimized out> #19 smbd_smb2_request_process_create (smb2req=smb2req@entry=0x80c2968) at ../source3/smbd/smb2_create.c:227 inbody = <optimized out> indyniov = <optimized out> in_oplock_level = <optimized out> in_impersonation_level = <optimized out> in_desired_access = <optimized out> in_file_attributes = <optimized out> in_share_access = <optimized out> in_create_disposition = <optimized out> in_create_options = <optimized out> in_name_offset = <optimized out> in_name_length = <optimized out> in_name_buffer = <optimized out> in_name_string = 0x80c2ce8 "New folder\\New folder\\New Text Document.txt" in_name_string_size = 43 name_offset = <optimized out> name_available_length = <optimized out> in_context_offset = <optimized out> in_context_length = <optimized out> in_context_blobs = {num_blobs = 4, blobs = 0x80c3078} context_offset = <optimized out> context_available_length = <optimized out> dyn_offset = <optimized out> status = <optimized out> ok = <optimized out> #20 0xfe5c30a4 in smbd_smb2_request_dispatch (req=req@entry=0x80c2968) at ../source3/smbd/smb2_server.c:2597 xconn = <optimized out> call = <optimized out> intf_v = <optimized out> inhdr = <optimized out> opcode = <optimized out> flags = <optimized out> mid = <optimized out> status = <optimized out> session_status = <optimized out> allowed_flags = <optimized out> return_value = <optimized out> x = <optimized out> signing_required = <optimized out> encryption_desired = false encryption_required = <optimized out> __FUNCTION__ = "smbd_smb2_request_dispatch" #21 0xfe5c3e4f in smbd_smb2_io_handler (fde_flags=<optimized out>, xconn=0x809cdc0) at ../source3/smbd/smb2_server.c:3890 err = <optimized out> sconn = <optimized out> state = 0x809ce34 req = <optimized out> min_recvfile_size = 4294967295 ret = <optimized out> retry = false status = <optimized out> now = <optimized out> #22 smbd_smb2_connection_handler (ev=0x8099b40, fde=0x80a93d8, flags=1, private_data=0x809cdc0) at ../source3/smbd/smb2_server.c:3928 xconn = 0x809cdc0 status = <optimized out> #23 0xfe7cbc76 in epoll_event_loop (tvalp=0x80475ac, epoll_ev=0x80991f8) at ../lib/tevent/tevent_epoll.c:728 fde = <optimized out> flags = <optimized out> mpx_fde = <optimized out> ret = <optimized out> i = 0 timeout = <optimized out> wait_errno = <optimized out> events = {{events = 1, data = {ptr = 0x80a93d8, fd = 134910936, u32 = 134910936, u64 = 134910936}}} #24 epoll_event_loop_once (ev=0x8099b40, location=0xfe6cba64 "../source3/smbd/process.c:4126") at ../lib/tevent/tevent_epoll.c:930 epoll_ev = 0x80991f8 tval = {tv_sec = 30, tv_usec = 843178} panic_triggered = false #25 0xfe7c9c1e in std_event_loop_once (ev=0x8099b40, location=0xfe6cba64 "../source3/smbd/process.c:4126") at ../lib/tevent/tevent_standard.c:114 glue_ptr = <optimized out> glue = 0x8099150 ret = <optimized out> #26 0xfe7c53d3 in _tevent_loop_once (ev=ev@entry=0x8099b40, location=location@entry=0xfe6cba64 "../source3/smbd/process.c:4126") at ../lib/tevent/tevent.c:726 ret = <optimized out> nesting_stack_ptr = 0x0 #27 0xfe7c55fc in tevent_common_loop_wait (ev=0x8099b40, location=0xfe6cba64 "../source3/smbd/process.c:4126") at ../lib/tevent/tevent.c:849 ret = <optimized out> #28 0xfe7c9b9e in std_event_loop_wait (ev=0x8099b40, location=0xfe6cba64 "../source3/smbd/process.c:4126") at ../lib/tevent/tevent_standard.c:145 glue_ptr = <optimized out> glue = 0x8099150 ret = <optimized out> #29 0xfe7c5698 in _tevent_loop_wait (ev=0x8099b40, location=location@entry=0xfe6cba64 "../source3/smbd/process.c:4126") at ../lib/tevent/tevent.c:868 No locals. #30 0xfe5afce5 in smbd_process (ev_ctx=ev_ctx@entry=0x8099b40, msg_ctx=msg_ctx@entry=0x80992f0, sock_fd=sock_fd@entry=41, interactive=interactive@entry=false) at ../source3/smbd/process.c:4126 trace_state = {ev = 0x8099b40, frame = 0x80bbee0} client = 0x80a3d08 sconn = 0x80a8d98 xconn = 0x809cdc0 locaddr = <optimized out> remaddr = <optimized out> ret = <optimized out> status = <optimized out> tv = {tv_sec = 1506034990, tv_usec = 686316} now = <optimized out> chroot_dir = <optimized out> rc = <optimized out> __func__ = "smbd_process" __FUNCTION__ = "smbd_process" #31 0x0805c7b1 in smbd_accept_connection (ev=0x8099b40, fde=0x80a4d10, flags=1, private_data=0x80a4cc0) at ../source3/smbd/server.c:1026 status = {v = 0} s = 0x0 msg_ctx = 0x80992f0 addr = {ss_family = 2, _ss_pad1 = "\312+\206G\273F", _ss_align = 0, _ss_pad2 = "\reY\374\004\b`\374\000\000\000\000\030x\004\b\000\000`\374\004\b`\374\250\247\t\b\030x\004\b\000\000\000\000\004\b`\374.\200R\374\273\070\204\376\000\000`\374\004\b`\374\250\247\t\b8x\004\b\213\201R\374\004\b`\374\000\000\000\000xx\004\b\021Y\332\376\224\257\205\376\000\000\000\000\210x\004\b~(\204\376\250\247\t\b(|\t\b\000\000\000\000\330lY\374\004\b`\374\000\000\000\000\270x\004\bY\241|\376\300x\004\b\324\371\t\b\004\b`\374\reY\374\004\b`\374\000\000\000\000;\241|\376\020\347}\376\310\371\t\b\300x\004\b\350x\004\b\225\247|\376\310x\004\b\300x\004\b\324\371\t\b\000\000`\374\004\b`\374"...} in_addrlen = 16 fd = 41 pid = <optimized out> __FUNCTION__ = "smbd_accept_connection" #32 0xfe7cbc76 in epoll_event_loop (tvalp=0x804792c, epoll_ev=0x80991f8) at ../lib/tevent/tevent_epoll.c:728 fde = <optimized out> flags = <optimized out> mpx_fde = <optimized out> ret = <optimized out> i = 0 timeout = <optimized out> wait_errno = <optimized out> events = {{events = 1, data = {ptr = 0x80a4d10, fd = 134892816, u32 = 134892816, u64 = 134892816}}} #33 epoll_event_loop_once (ev=0x8099b40, location=0x8063c6d "../source3/smbd/server.c:1393") at ../lib/tevent/tevent_epoll.c:930 epoll_ev = 0x80991f8 tval = {tv_sec = 883, tv_usec = 381616} panic_triggered = false #34 0xfe7c9c1e in std_event_loop_once (ev=0x8099b40, location=0x8063c6d "../source3/smbd/server.c:1393") at ../lib/tevent/tevent_standard.c:114 glue_ptr = <optimized out> glue = 0x8099150 ret = <optimized out> #35 0xfe7c53d3 in _tevent_loop_once (ev=ev@entry=0x8099b40, location=location@entry=0x8063c6d "../source3/smbd/server.c:1393") at ../lib/tevent/tevent.c:726 ret = <optimized out> nesting_stack_ptr = 0x0 #36 0xfe7c55fc in tevent_common_loop_wait (ev=0x8099b40, location=0x8063c6d "../source3/smbd/server.c:1393") at ../lib/tevent/tevent.c:849 ret = <optimized out> #37 0xfe7c9b9e in std_event_loop_wait (ev=0x8099b40, location=0x8063c6d "../source3/smbd/server.c:1393") at ../lib/tevent/tevent_standard.c:145 glue_ptr = <optimized out> glue = 0x8099150 ret = <optimized out> #38 0xfe7c5698 in _tevent_loop_wait (ev=0x8099b40, location=location@entry=0x8063c6d "../source3/smbd/server.c:1393") at ../lib/tevent/tevent.c:868 No locals. #39 0x0805ef55 in smbd_parent_loop (parent=<optimized out>, ev_ctx=<optimized out>) at ../source3/smbd/server.c:1393 trace_state = {frame = 0x80a3b50} ret = 0 #40 main (argc=<optimized out>, argv=0x8047de0) at ../source3/smbd/server.c:2160 is_daemon = <optimized out> interactive = <optimized out> Fork = <optimized out> no_process_group = <optimized out> log_stdout = <optimized out> ports = 0x0 profile_level = 0x0 opt = <optimized out> pc = <optimized out> print_build_options = <optimized out> main_server_id = {pid = 17505, task_id = 0, vnn = 4294967295, unique_id = 3533014807489980013} long_options = {{longName = 0x0, shortName = 0 '\000', argInfo = 4, arg = 0xfc6e9b60 <poptHelpOptions>, val = 0, descrip = 0x8064253 "Help options:", argDescrip = 0x0}, {longName = 0x8064261 "daemon", shortName = 68 'D', argInfo = 0, arg = 0x0, val = 1000, descrip = 0x8064268 "Become a daemon (default)", argDescrip = 0x0}, {longName = 0x8064282 "interactive", shortName = 105 'i', argInfo = 0, arg = 0x0, val = 1001, descrip = 0x8061d74 "Run interactive (not a daemon)", argDescrip = 0x0}, {longName = 0x806428e "foreground", shortName = 70 'F', argInfo = 0, arg = 0x0, val = 1002, descrip = 0x8061d94 "Run daemon in foreground (for daemontools, etc.)", argDescrip = 0x0}, {longName = 0x8064299 "no-process-group", shortName = 0 '\000', argInfo = 0, arg = 0x0, val = 1003, descrip = 0x8061dc8 "Don't create a new process group", argDescrip = 0x0}, {longName = 0x80642aa "log-stdout", shortName = 83 'S', argInfo = 0, arg = 0x0, val = 1004, descrip = 0x80642b5 "Log to stdout", argDescrip = 0x0}, { longName = 0x80642c3 "build-options", shortName = 98 'b', argInfo = 0, arg = 0x0, val = 98, descrip = 0x80642d1 "Print build options", argDescrip = 0x0}, {longName = 0x80642e5 "port", shortName = 112 'p', argInfo = 1, arg = 0x8047b04, val = 0, descrip = 0x80642ea "Listen on the specified ports", argDescrip = 0x0}, {longName = 0x8064308 "profiling-level", shortName = 80 'P', argInfo = 1, arg = 0x8047b08, val = 0, descrip = 0x8064318 "Set profiling level", argDescrip = 0x806432c "PROFILE_LEVEL"}, {longName = 0x0, shortName = 0 '\000', argInfo = 4, arg = 0xfee239e0 <popt_common_samba>, val = 0, descrip = 0x806433a "Common samba options:", argDescrip = 0x0}, {longName = 0x0, shortName = 0 '\000', argInfo = 0, arg = 0x0, val = 0, descrip = 0x0, argDescrip = 0x0}} parent = <optimized out> frame = <optimized out> status = <optimized out> ev_ctx = <optimized out> msg_ctx = <optimized out> server_id = {pid = 17506, task_id = 0, vnn = 4294967295, unique_id = 11824355283717389693} se = <optimized out> profiling_level = <optimized out> np_dir = <optimized out> smbd_shim_fns = {cancel_pending_lock_requests_by_fid = 0x8056794 <smbd_cancel_pending_lock_requests_by_fid@plt>, send_stat_cache_delete_message = 0x80567a4 <smbd_send_stat_cache_delete_message@plt>, change_to_root_user = 0x80567b4 <smbd_change_to_root_user@plt>, become_authenticated_pipe_user = 0x80567c4 <smbd_become_authenticated_pipe_user@plt>, unbecome_authenticated_pipe_user = 0x80567d4 <smbd_unbecome_authenticated_pipe_user@plt>, contend_level2_oplocks_begin = 0x80567e4 <smbd_contend_level2_oplocks_begin@plt>, contend_level2_oplocks_end = 0x80567f4 <smbd_contend_level2_oplocks_end@plt>, become_root = 0x8056804 <smbd_become_root@plt>, unbecome_root = 0x8056814 <smbd_unbecome_root@plt>, exit_server = 0x8056824 <smbd_exit_server@plt>, exit_server_cleanly = 0x8056834 <smbd_exit_server_cleanly@plt>} __FUNCTION__ = "main" __func__ = "main" quit Detaching from program: /usr/pkg/sbin/smbd, process 17516
You're going to need to walk into this with gdb to debug. Add the line: panic action = /bin/sleep 99999 to the [global] section of your smb.conf, and when it dies attach to the parent process of the sleep with gdb. The code looks like: 1522 static int store_cwd_data(vfs_handle_struct *handle, 1523 const char *connectpath) 1524 { 1525 struct shadow_copy2_private *priv = NULL; 1526 struct smb_filename *cwd_fname = NULL; 1527 1528 SMB_VFS_HANDLE_GET_DATA(handle, priv, struct shadow_copy2_private, 1529 return -1); 1530 1531 cwd_fname = SMB_VFS_NEXT_GETWD(handle, talloc_tos()); 1532 if (cwd_fname == NULL) { 1533 return -1; 1534 } 1535 DBG_DEBUG("shadow cwd = %s\n", cwd_fname->base_name); 1536 1537 /* 1538 * Now we're modifying the priv data. Any 1539 * failures here are terminal. 1540 */ 1541 1542 TALLOC_FREE(priv->shadow_cwd); 1543 priv->shadow_cwd = talloc_strdup(priv, cwd_fname->base_name); 1544 TALLOC_FREE(cwd_fname); 1545 if (priv->shadow_cwd == NULL) { 1546 smb_panic("talloc failed\n"); 1547 } and it seems to be dieing with priv->shadow_cwd == NULL, which means the line: priv->shadow_cwd = talloc_strdup(priv, cwd_fname->base_name); returned NULL. If: 1531 cwd_fname = SMB_VFS_NEXT_GETWD(handle, talloc_tos()); didn't return NULL, then I really don't see how the talloc can have failed here (I'm assuming you're not out of memory :-). You'll have to debug to explain I'm afraid. We need to know what *exactly* is in cwd_fname after the SMB_VFS_NEXT_GETWD call.
I was able to break on source3/modules/vfs_shadow_copy2.c:1527 and next through the function. It looks like the smb_filename that comes back is rather empty: (gdb) print cwd_fname $9 = (struct smb_filename *) 0x80c4b70 (gdb) print *cwd_fname $10 = {base_name = 0x0, stream_name = 0x0, original_lcomp = 0x0, flags = 0, st = {st_ex_dev = 0, st_ex_ino = 0, st_ex_mode = 0, st_ex_nlink = 0, st_ex_uid = 0, st_ex_gid = 0, st_ex_rdev = 0, st_ex_size = 0, st_ex_atime = {tv_sec = 0, tv_nsec = 0}, st_ex_mtime = {tv_sec = 0, tv_nsec = 0}, st_ex_ctime = {tv_sec = 0, tv_nsec = 0}, st_ex_btime = {tv_sec = 0, tv_nsec = 0}, st_ex_calculated_birthtime = false, st_ex_blksize = 0, st_ex_blocks = 0, st_ex_flags = 0, st_ex_mask = 0}} It looks like the result of getwd is never checked when constructing the smb_filename that gets returned.
I tweaked the patch to check base_name instead of the cwd_fname pointer: - if (cwd_fname == NULL) { - smb_panic("getwd failed\n"); + if (cwd_fname->base_name == NULL) { + return -1; And now it's not crashing when I try to create files. Any other operations I should test?
Oh - you've found a bug in the vfs_default.c getwd() handling ! It should be returning NULL on error, not an invalid struct smb_filename. I'll log a separate bug for that, and make this dependent on it.
Created attachment 13646 [details] Prerequisite patch Can you try adding this patch also, and *then* applying the specific patch for this bug. I think with all these patches the bug should be fixed. Sorry for the problem.
Looks like that really broke things. With shadow_copy2 enabled, every location I tried to poke returned NT_STATUS_ACCESS_DENIED. With shadow_copy2 disabled, it hits the smb_panic at source3/smbd/vfs.c:887. Here's a backtrace in the call to vfs_GetWd that returns null: #0 vfs_GetWd (ctx=ctx@entry=0x80b64c8, conn=conn@entry=0x80b64c8) at ../source3/smbd/vfs.c:903 current_dir_fname = 0x80b38a8 key = {devid = 579619958582465752, inode = 579619065229424920, extid = 18334714099516047364} smb_fname_dot = <optimized out> smb_fname_full = <optimized out> result = <optimized out> __FUNCTION__ = "vfs_GetWd" #1 0xfe598c72 in vfs_ChDir (conn=conn@entry=0x80b64c8, smb_fname=smb_fname@entry=0x80b7530) at ../source3/smbd/vfs.c:885 ret = <optimized out> __FUNCTION__ = "vfs_ChDir" #2 0xfe529e4e in open_dir_safely (ctx=0x80b74f0, conn=0x80b64c8, smb_dname=0x80b7530, wcard=0x0, attr=0) at ../source3/smbd/dir.c:1690 dir_hnd = 0x0 smb_fname_cwd = 0x0 saved_dir_fname = 0x80b77f0 #3 0xfe52b327 in OpenDir (mem_ctx=<optimized out>, conn=<optimized out>, conn@entry=0x80b64c8, smb_dname=<optimized out>, smb_dname@entry=0x80b7530, mask=mask@entry=0x0, attr=attr@entry=0) at ../source3/smbd/dir.c:1745 No locals. #4 0xfe57f992 in get_real_filename_full_scan (conn=0x80b64c8, path=0x80ae260 "New folder/New folder", path@entry=0x59c88924 <error: Cannot access memory at address 0x59c88924>, name=0x80add96 "New Text Document (2).txt", mangled=false, mem_ctx=0x80b74f0, found_name=0x804702c) at ../source3/smbd/filename.c:1381 cur_dir = <optimized out> dname = 0x0 talloced = <optimized out> unmangled_name = <optimized out> curpos = 134929814 smb_fname = 0x80b7530 __FUNCTION__ = "get_real_filename_full_scan" #5 0xfe57ff83 in get_real_filename (conn=0x80add96, conn@entry=0x80b64c8, path=0x0, name=0x80b74f0 "\360u\v\b\002", mem_ctx=0x804702c, found_name=found_name@entry=0x804702c) at ../source3/smbd/filename.c:1465 ret = <optimized out> mangled = <optimized out> #6 0xfe580aa4 in unix_convert (ctx=0x80afac8, conn=conn@entry=0x80b64c8, orig_path=0x80b1ae0 "New folder/New folder/New Text Document (2).txt", smb_fname_out=0x80472fc, ucf_flags=ucf_flags@entry=0) at ../source3/smbd/filename.c:920 found_name = 0x0 smb_fname = 0x80b0ee8 cnull = 0 '\000' start = 0x80add96 "New Text Document (2).txt" end = 0x0 stream = 0x0 component_was_mangled = false name_has_wildcard = false posix_pathnames = false allow_wcard_last_component = false save_last_component = false snapshot_path = false status = <optimized out> ret = <optimized out> __FUNCTION__ = "unix_convert" #7 0xfe581c29 in filename_convert_internal (ctx=ctx@entry=0x80afac8, conn=conn@entry=0x80b64c8, smbreq=smbreq@entry=0x0, name_in=<optimized out>, name_in@entry=0x80b1ae0 "New folder/New folder/New Text Document (2).txt", ucf_flags=ucf_flags@entry=0, ppath_contains_wcard=ppath_contains_wcard@entry=0x0, pp_smb_fname=pp_smb_fname@entry=0x80472fc) at ../source3/smbd/filename.c:1619 status = <optimized out> __FUNCTION__ = "filename_convert_internal" #8 0xfe581f9e in filename_convert (ctx=0x80afac8, conn=0x80b64c8, name_in=0x80b1ae0 "New folder/New folder/New Text Document (2).txt", ucf_flags=0, ppath_contains_wcard=ppath_contains_wcard@entry=0x0, pp_smb_fname=pp_smb_fname@entry=0x80472fc) at ../source3/smbd/filename.c:1664 No locals. #9 0xfe5ce0c8 in smbd_smb2_create_send (in_context_blobs=..., in_name=<optimized out>, in_create_options=<optimized out>, in_create_disposition=<optimized out>, in_share_access=<optimized out>, in_file_attributes=<optimized out>, in_desired_access=<optimized out>, in_impersonation_level=<optimized out>, in_oplock_level=<optimized out>, smb2req=<optimized out>, ev=<optimized out>, mem_ctx=<optimized out>) at ../source3/smbd/smb2_create.c:1114 smb_fname = 0x0 ucf_flags = <optimized out> ea_list = <optimized out> sec_desc = <optimized out> durable_requested = <optimized out> need_replay_cache = <optimized out> mxac = <optimized out> max_access_time = <optimized out> allocation_size = <optimized out> lease_ptr = <optimized out> lease_len = <optimized out> op = 0x0 fname = <optimized out> secd = <optimized out> _create_guid = {time_low = 0, time_mid = 0, time_hi_and_version = 0, clock_seq = "\000", node = "\000\000\000\000\000"} create_guid = <optimized out> do_durable_reconnect = <optimized out> persistent_id = <optimized out> exta = <optimized out> qfid = <optimized out> update_open = <optimized out> lease = {lease_key = {data = {0, 0}}, lease_state = 0, lease_flags = 0, lease_duration = 0, parent_lease_key = {data = {0, 0}}, lease_version = 0, lease_epoch = 0} alsi = <optimized out> twrp = <optimized out> durable_timeout_msec = <optimized out> state = 0x80afba8 smb1req = <optimized out> req = <optimized out> result = 0x0 dhnc = <optimized out> dh2c = <optimized out> status = <optimized out> info = 0 requested_oplock_level = <optimized out> rqls = <optimized out> dhnq = <optimized out> dh2q = <optimized out> replay_operation = <optimized out> #10 smbd_smb2_request_process_create (smb2req=smb2req@entry=0x80af338) at ../source3/smbd/smb2_create.c:227 inbody = <optimized out> indyniov = <optimized out> in_oplock_level = <optimized out> in_impersonation_level = <optimized out> in_desired_access = <optimized out> in_file_attributes = <optimized out> in_share_access = <optimized out> in_create_disposition = <optimized out> in_create_options = <optimized out> in_name_offset = <optimized out> in_name_length = <optimized out> in_name_buffer = <optimized out> in_name_string = 0x80af658 "New folder\\New folder\\New Text Document (2).txt" in_name_string_size = 47 name_offset = <optimized out> name_available_length = <optimized out> in_context_offset = <optimized out> in_context_length = <optimized out> in_context_blobs = {num_blobs = 3, blobs = 0x80af9e8} context_offset = <optimized out> context_available_length = <optimized out> dyn_offset = <optimized out> status = <optimized out> ok = <optimized out> #11 0xfe5c30a4 in smbd_smb2_request_dispatch (req=req@entry=0x80af338) at ../source3/smbd/smb2_server.c:2597 xconn = <optimized out> call = <optimized out> intf_v = <optimized out> inhdr = <optimized out> opcode = <optimized out> flags = <optimized out> mid = <optimized out> status = <optimized out> session_status = <optimized out> allowed_flags = <optimized out> return_value = <optimized out> x = <optimized out> signing_required = <optimized out> encryption_desired = false encryption_required = <optimized out> __FUNCTION__ = "smbd_smb2_request_dispatch" #12 0xfe5c3e4f in smbd_smb2_io_handler (fde_flags=<optimized out>, xconn=0x809c7b8) at ../source3/smbd/smb2_server.c:3890 err = <optimized out> sconn = <optimized out> state = 0x809c82c req = <optimized out> min_recvfile_size = 4294967295 ret = <optimized out> retry = false status = <optimized out> now = <optimized out> #13 smbd_smb2_connection_handler (ev=0x8099150, fde=0x80a7d88, flags=1, private_data=0x809c7b8) at ../source3/smbd/smb2_server.c:3928 xconn = 0x809c7b8 status = <optimized out> #14 0xfe7cbc76 in epoll_event_loop (tvalp=0x804750c, epoll_ev=0x80992a0) at ../lib/tevent/tevent_epoll.c:728 fde = <optimized out> flags = <optimized out> mpx_fde = <optimized out> ret = <optimized out> i = 0 timeout = <optimized out> wait_errno = <optimized out> events = {{events = 1, data = {ptr = 0x80a7d88, fd = 134905224, u32 = 134905224, u64 = 134905224}}} #15 epoll_event_loop_once (ev=0x8099150, location=0xfe6cba64 "../source3/smbd/process.c:4126") at ../lib/tevent/tevent_epoll.c:930 epoll_ev = 0x80992a0 tval = {tv_sec = 0, tv_usec = 998118} panic_triggered = false #16 0xfe7c9c1e in std_event_loop_once (ev=0x8099150, location=0xfe6cba64 "../source3/smbd/process.c:4126") at ../lib/tevent/tevent_standard.c:114 glue_ptr = <optimized out> glue = 0x80991f8 ret = <optimized out> #17 0xfe7c53d3 in _tevent_loop_once (ev=ev@entry=0x8099150, location=location@entry=0xfe6cba64 "../source3/smbd/process.c:4126") at ../lib/tevent/tevent.c:726 ret = <optimized out> nesting_stack_ptr = 0x0 #18 0xfe7c55fc in tevent_common_loop_wait (ev=0x8099150, location=0xfe6cba64 "../source3/smbd/process.c:4126") at ../lib/tevent/tevent.c:849 ret = <optimized out> #19 0xfe7c9b9e in std_event_loop_wait (ev=0x8099150, location=0xfe6cba64 "../source3/smbd/process.c:4126") at ../lib/tevent/tevent_standard.c:145 glue_ptr = <optimized out> glue = 0x80991f8 ret = <optimized out> #20 0xfe7c5698 in _tevent_loop_wait (ev=0x8099150, location=location@entry=0xfe6cba64 "../source3/smbd/process.c:4126") at ../lib/tevent/tevent.c:868 No locals. #21 0xfe5afce5 in smbd_process (ev_ctx=ev_ctx@entry=0x8099150, msg_ctx=msg_ctx@entry=0x8099398, sock_fd=sock_fd@entry=41, interactive=interactive@entry=false) at ../source3/smbd/process.c:4126 trace_state = {ev = 0x8099150, frame = 0x80b74f0} client = 0x809daf0 sconn = 0x80a8a90 xconn = 0x809c7b8 locaddr = <optimized out> remaddr = <optimized out> ret = <optimized out> status = <optimized out> tv = {tv_sec = 1507074148, tv_usec = 938243} now = <optimized out> chroot_dir = <optimized out> rc = <optimized out> __func__ = "smbd_process" __FUNCTION__ = "smbd_process" #22 0x0805c7b1 in smbd_accept_connection (ev=0x8099150, fde=0x80a6d18, flags=1, private_data=0x80a6cc8) at ../source3/smbd/server.c:1026 status = {v = 0} s = 0x0 msg_ctx = 0x8099398 addr = {ss_family = 2, _ss_pad1 = "\325\370\206G\372\061", _ss_align = 0, _ss_pad2 = "\reY\374\004\b`\374\000\000\000\000xw\004\b\000\000`\374\004\b`\374 \235\t\bxw\004\b\000\000\000\000\004\b`\374.\200R\374\273\070\204\376\000\000`\374\004\b`\374 \235\t\b\230w\004\b\213\201R\374\004\b`\374\000\000\000\000\330w\004\b\021Y\332\376\224\257\205\376\000\000\000\000\350w\004\b~(\204\376 \235\t\bh\032\n\b\000\000\000\000\330lY\374\004\b`\374\000\000\000\000\030x\004\bY\241|\376 x\004\bt\364\t\b\004\b`\374\reY\374\004\b`\374\000\000\000\000;\241|\376\020\347}\376h\364\t\b x\004\bHx\004\b\225\247|\376(x\004\b x\004\bt\364\t\b\000\000`\374\004\b`\374"...} in_addrlen = 16 fd = 41 pid = <optimized out> __FUNCTION__ = "smbd_accept_connection" #23 0xfe7cbc76 in epoll_event_loop (tvalp=0x804788c, epoll_ev=0x80992a0) at ../lib/tevent/tevent_epoll.c:728 fde = <optimized out> flags = <optimized out> mpx_fde = <optimized out> ret = <optimized out> i = 0 timeout = <optimized out> wait_errno = <optimized out> events = {{events = 1, data = {ptr = 0x80a6d18, fd = 134901016, u32 = 134901016, u64 = 134901016}}} #24 epoll_event_loop_once (ev=0x8099150, location=0x8063c6d "../source3/smbd/server.c:1393") at ../lib/tevent/tevent_epoll.c:930 epoll_ev = 0x80992a0 tval = {tv_sec = 407, tv_usec = 144170} panic_triggered = false #25 0xfe7c9c1e in std_event_loop_once (ev=0x8099150, location=0x8063c6d "../source3/smbd/server.c:1393") at ../lib/tevent/tevent_standard.c:114 glue_ptr = <optimized out> glue = 0x80991f8 ret = <optimized out> #26 0xfe7c53d3 in _tevent_loop_once (ev=ev@entry=0x8099150, location=location@entry=0x8063c6d "../source3/smbd/server.c:1393") at ../lib/tevent/tevent.c:726 ret = <optimized out> nesting_stack_ptr = 0x0 #27 0xfe7c55fc in tevent_common_loop_wait (ev=0x8099150, location=0x8063c6d "../source3/smbd/server.c:1393") at ../lib/tevent/tevent.c:849 ret = <optimized out> #28 0xfe7c9b9e in std_event_loop_wait (ev=0x8099150, location=0x8063c6d "../source3/smbd/server.c:1393") at ../lib/tevent/tevent_standard.c:145 glue_ptr = <optimized out> glue = 0x80991f8 ret = <optimized out> #29 0xfe7c5698 in _tevent_loop_wait (ev=0x8099150, location=location@entry=0x8063c6d "../source3/smbd/server.c:1393") at ../lib/tevent/tevent.c:868 No locals. #30 0x0805ef55 in smbd_parent_loop (parent=<optimized out>, ev_ctx=<optimized out>) at ../source3/smbd/server.c:1393 trace_state = {frame = 0x809deb8} ret = 0 #31 main (argc=<optimized out>, argv=0x8047d48) at ../source3/smbd/server.c:2160 is_daemon = <optimized out> interactive = <optimized out> Fork = <optimized out> no_process_group = <optimized out> log_stdout = <optimized out> ports = 0x0 profile_level = 0x0 opt = <optimized out> pc = <optimized out> print_build_options = <optimized out> main_server_id = {pid = 6167, task_id = 0, vnn = 4294967295, unique_id = 12535287533572478642} long_options = {{longName = 0x0, shortName = 0 '\000', argInfo = 4, arg = 0xfc6e9b60 <poptHelpOptions>, val = 0, descrip = 0x8064253 "Help options:", argDescrip = 0x0}, {longName = 0x8064261 "daemon", shortName = 68 'D', argInfo = 0, arg = 0x0, val = 1000, descrip = 0x8064268 "Become a daemon (default)", argDescrip = 0x0}, {longName = 0x8064282 "interactive", shortName = 105 'i', argInfo = 0, arg = 0x0, val = 1001, descrip = 0x8061d74 "Run interactive (not a daemon)", argDescrip = 0x0}, { longName = 0x806428e "foreground", shortName = 70 'F', argInfo = 0, arg = 0x0, val = 1002, descrip = 0x8061d94 "Run daemon in foreground (for daemontools, etc.)", argDescrip = 0x0}, { longName = 0x8064299 "no-process-group", shortName = 0 '\000', argInfo = 0, arg = 0x0, val = 1003, descrip = 0x8061dc8 "Don't create a new process group", argDescrip = 0x0}, { longName = 0x80642aa "log-stdout", shortName = 83 'S', argInfo = 0, arg = 0x0, val = 1004, descrip = 0x80642b5 "Log to stdout", argDescrip = 0x0}, {longName = 0x80642c3 "build-options", shortName = 98 'b', argInfo = 0, arg = 0x0, val = 98, descrip = 0x80642d1 "Print build options", argDescrip = 0x0}, {longName = 0x80642e5 "port", shortName = 112 'p', argInfo = 1, arg = 0x8047a64, val = 0, descrip = 0x80642ea "Listen on the specified ports", argDescrip = 0x0}, { longName = 0x8064308 "profiling-level", shortName = 80 'P', argInfo = 1, arg = 0x8047a68, val = 0, descrip = 0x8064318 "Set profiling level", argDescrip = 0x806432c "PROFILE_LEVEL"}, {longName = 0x0, shortName = 0 '\000', argInfo = 4, arg = 0xfee239e0 <popt_common_samba>, val = 0, descrip = 0x806433a "Common samba options:", argDescrip = 0x0}, {longName = 0x0, shortName = 0 '\000', argInfo = 0, arg = 0x0, val = 0, descrip = 0x0, argDescrip = 0x0}} parent = <optimized out> frame = <optimized out> status = <optimized out> ev_ctx = <optimized out> msg_ctx = <optimized out> server_id = {pid = 6168, task_id = 0, vnn = 4294967295, unique_id = 13867607488433539256} se = <optimized out> profiling_level = <optimized out> np_dir = <optimized out> smbd_shim_fns = { cancel_pending_lock_requests_by_fid = 0x8056794 <smbd_cancel_pending_lock_requests_by_fid@plt>, send_stat_cache_delete_message = 0x80567a4 <smbd_send_stat_cache_delete_message@plt>, change_to_root_user = 0x80567b4 <smbd_change_to_root_user@plt>, become_authenticated_pipe_user = 0x80567c4 <smbd_become_authenticated_pipe_user@plt>, unbecome_authenticated_pipe_user = 0x80567d4 <smbd_unbecome_authenticated_pipe_user@plt>, contend_level2_oplocks_begin = 0x80567e4 <smbd_contend_level2_oplocks_begin@plt>, contend_level2_oplocks_end = 0x80567f4 <smbd_contend_level2_oplocks_end@plt>, become_root = 0x8056804 <smbd_become_root@plt>, unbecome_root = 0x8056814 <smbd_unbecome_root@plt>, exit_server = 0x8056824 <smbd_exit_server@plt>, exit_server_cleanly = 0x8056834 <smbd_exit_server_cleanly@plt>} __FUNCTION__ = "main" __func__ = "main"
OK, I'm puzzled now. The prerequisite patch should ensure that the lowest level vfswrap_getwd() can never return a half-constructed struct smb_filename pointer, but only NULL on error - which is certainly what is needed as the low level fix. Returning an initialized struct smb_filename pointer where base_name is NULL is *definitely* the wrong thing to do :-). I'll take a look at the backtrace tomorrow and try and figure out what is going on.
Can you let me know which code path is being taken on your system through sys_getwd() ? Can you test this on 4.7.x (the prerequisite patch was created and tested on 4.7.x) ? Not being able to reproduce locally makes this very frustrating to work on. Can you attach with gdb to a single instance (smbd -i) with smbclient as the client and step through this to help me debug it ?
>OK, I'm puzzled now. The prerequisite patch should ensure that the lowest level vfswrap_getwd() can never return a half-constructed struct smb_filename pointer Sorry, maybe I wasn't clear. It's returning null properly now. The panic I'm talking about is this one in vfs_ChDir: conn->cwd_fname = vfs_GetWd(conn, conn); if (conn->cwd_fname == NULL) { smb_panic("con->cwd getwd failed\n"); /* NOTREACHED */ return -1; } This makes the server pretty unusable on platforms where getcwd is unreliable. I've been testing the two patches against 4.7.0. Here's a partial bt showing where getcwd gets used: #0 0xfc5188c6 in getcwd () from /lib/libc.so.1 #1 0xfdfb88b6 in sys_getwd () at ../source3/lib/system.c:592 #2 0xfe4dfd68 in vfswrap_getwd (handle=0x808db30, ctx=0x80aa470) at ../source3/modules/vfs_default.c:2227 #3 0xfe597c03 in smb_vfs_call_getwd (handle=<optimized out>, ctx=0x80aa470) at ../source3/smbd/vfs.c:2148 #4 0xfe5988ec in vfs_GetWd (ctx=ctx@entry=0x80aa470, conn=conn@entry=0x80aa470) at ../source3/smbd/vfs.c:965 #5 0xfe598c72 in vfs_ChDir (conn=conn@entry=0x80aa470, smb_fname=smb_fname@entry=0x80becd8) at ../source3/smbd/vfs.c:885 #6 0xfe529e4e in open_dir_safely (ctx=0x80bec98, conn=0x80aa470, smb_dname=0x80becd8, wcard=0x0, attr=0) at ../source3/smbd/dir.c:1690 #7 0xfe52b327 in OpenDir (mem_ctx=<optimized out>, conn=<optimized out>, conn@entry=0x80aa470, smb_dname=<optimized out>, smb_dname@entry=0x80becd8, mask=mask@entry=0x0, attr=attr@entry=0) at ../source3/smbd/dir.c:1745 You can probably simulate my getcwd issue with LD_PRELOAD. I don't have any linux boxes running samba to test this against, but it worked on linux against `pwd`. Just change the string to be the dir you want to simulate in: #define _GNU_SOURCE #include <unistd.h> #include <string.h> #include <dlfcn.h> static char* (*real_getcwd)(char *buf, size_t size) = NULL; static char* (*real_getwd)(char *buf) = NULL; char *getcwd(char *buf, size_t size) { return NULL; real_getcwd = dlsym(RTLD_NEXT, "getcwd"); char *ret = real_getcwd(buf, size); if(ret && strcmp(ret, "/user/bldewolf/cwdwrap") == 0) { return NULL; } return ret; } char *getwd(char *buf) { return NULL; real_getwd = dlsym(RTLD_NEXT, "getwd"); char *ret = real_getwd(buf); if(ret && strcmp(ret, "/user/bldewolf/cwdwrap") == 0) { return NULL; } return ret; }
Ah, thanks. The return NULL behaviour for getwd is correct now (and pushed to master). I have to examine all the code paths before possibly changing the vfs_ChDir() behaviour. It's pretty clear from the intent of the vfs_ChDir() code that smbd expects that if chdir() succeeds, that getwd() must also succeed. If we change that behaviour, are we introducing a security hole somewhere ?
Created attachment 13651 [details] generic patch for smbd OK, can you try this generic patch for smbd. It changes the behaviour for chdir+getwd()-fail to be return to previous directory, instead of panic. This should simply prevent you from chdir()'ing into a directory for which you can't getwd(). You will still need the prerequisite patch. Can you test this both with and without the shadow_copy2 module ? If we still crash with the shadow_copy2 module then we probably need both this and the previous 'Updated git-am patch for master.' patch. Cheers, Jeremy.
Alright, I built and tested with all three patches applied. It's now working with shadow_copy2 and without. I was actually the cause of the server returning permission denied for everything when shadow_copy2 was enabled. Because it tries to store the cwd before doing a chdir, it's very picky about what directory the server starts in. I was starting the server in /root, and since the server starts impersonating the user, every getcwd call fails before it can chdir out of /root. After starting the daemon in /, shadow_copy2 was happy again. I'm still concerned about one regression (from pre-4.6) that remains: when the user is in a directory where getcwd doesn't work, they are unable to create/modify/delete any files. I've been checking if it gets fixed incidentally, but no dice. I'll try poking at it to see if I can find what's failing.
Well being as the intent was that smbd be unable to chdir() into a directory where it can't then get the result via getwd(), I'm not too worried about that as a regression - I don't think it should have been allowing that in the first place. Just to confirm - all 3 patches are needed ? Is the first patch: https://attachments.samba.org/attachment.cgi?id=13601 needed to make things work with a shadow_copy2 share ?
With the patch: https://attachments.samba.org/attachment.cgi?id=13651 that prevents chdir() into a directory where getwd() fails, I think I can simplify the first patch: https://attachments.samba.org/attachment.cgi?id=13601 as it shouldn't need to store off the existing directory, just correctly handle the chdir() fail. I'll upload a modified version of that one tomorrow.
(In reply to Jeremy Allison from comment #31) Hmmm. In fact, maybe patch: https://attachments.samba.org/attachment.cgi?id=13601 isn't needed at all for shadow_copy2 shares, now that the underlying chdir() call should fail if the target directory is unreadable with getwd().
I rebuilt samba 4.7.0 with two patches: https://bugzilla.samba.org/attachment.cgi?id=13646 https://bugzilla.samba.org/attachment.cgi?id=13651 The server runs fine with shadow_copy2 enabled now. Looks like that fixes it.
Created attachment 13676 [details] git-am fix for 4.7.next. Cherry-picked from master.
Reassigning to metzolin for inclusion in 4.7. :)
(In reply to Ralph Böhme from comment #35) Pushed to autobuild-v4-7-test.
(In reply to Karolin Seeger from comment #36) Pushed to v4-7-test. Closing out bug report. Thanks!
Well, I started preparing to deploy 4.7.4 and noticed I still get crashes when I try to enable the shadow_copy2 module. It looks like I messed up testing last October and the patch https://attachments.samba.org/attachment.cgi?id=13601 is still required. Should I re-open this bug or should I make a new one?
New one please - add the patch you think is needed to it and give me a *GOOD* reproducible scenario. Thanks. Jeremy.