vfs_crossrename not working in samba-4.15.*
Pavel Filipenský
pfilipensky at samba.org
Fri Oct 7 13:28:28 UTC 2022
Actually, the issue is present even without vfs_recycle - i.e. the
vfs_crossrename does not work if the rename is across filesystems.
And the root cause is almost the same:
1) source3/modules/vfs_crossrename.c: copy_reg() is missing ENOENT check
2) Adding if (ret == -1 && errno != ENOENT)
to copy_reg() causes the exact panic - "assert failed:
share_mode_lock_key_refcount == 0"
The only difference is that with recycle module, the initial grab of
share_mode_lock_key_refcount was done here:
Old value = 0
New value = 1
get_share_mode_lock_internal (id=..., servicepath=0x0, smb_fname=0x0,
old_write_time=0x0, lck=0x7fffa9901980) at
../../source3/locking/share_mode_lock.c:972
972 if (static_share_mode_data != NULL) {
#0 get_share_mode_lock_internal (id=..., servicepath=0x0,
smb_fname=0x0, old_write_time=0x0, lck=0x7fffa9901980) at
../../source3/locking/share_mode_lock.c:972
#1 0x00007fc04b1bfa24 in share_mode_entry_prepare_lock_fn
(glck=0x7fffa9901190, cb_private=0x7fffa9901760) at
../../source3/locking/share_mode_lock.c:2952
#2 0x00007fc04b05c7d2 in g_lock_lock_cb_run_and_store
(cb_state=0x7fffa9901190) at ../../source3/lib/g_lock.c:597
#3 0x00007fc04b05e8c1 in g_lock_lock_simple_fn (rec=0x7fffa99014a0,
value=..., private_data=0x7fffa9901630) at ../../source3/lib/g_lock.c:1212
#4 0x00007fc04b05833d in dbwrap_watched_do_locked_fn
(backend_rec=0x7fffa9901350, backend_value=...,
private_data=0x7fffa9901470) at ../../source3/lib/dbwrap/dbwrap_watch.c:458
#5 0x00007fc04aa33e44 in db_tdb_do_locked (db=0x5653790ca050, key=...,
fn=0x7fc04b0582ab <dbwrap_watched_do_locked_fn>,
private_data=0x7fffa9901470) at ../../lib/dbwrap/dbwrap_tdb.c:208
#6 0x00007fc04aa304db in dbwrap_do_locked (db=0x5653790ca050, key=...,
fn=0x7fc04b0582ab <dbwrap_watched_do_locked_fn>,
private_data=0x7fffa9901470) at ../../lib/dbwrap/dbwrap.c:553
#7 0x00007fc04b058435 in dbwrap_watched_do_locked (db=0x5653790cf910,
key=..., fn=0x7fc04b05e4fa <g_lock_lock_simple_fn>,
private_data=0x7fffa9901630) at ../../source3/lib/dbwrap/dbwrap_watch.c:480
#8 0x00007fc04aa304db in dbwrap_do_locked (db=0x5653790cf910, key=...,
fn=0x7fc04b05e4fa <g_lock_lock_simple_fn>, private_data=0x7fffa9901630)
at ../../lib/dbwrap/dbwrap.c:553
#9 0x00007fc04b05eb28 in g_lock_lock (ctx=0x565379020280, key=...,
type=G_LOCK_WRITE, timeout=..., cb_fn=0x7fc04b1bf90d
<share_mode_entry_prepare_lock_fn>, cb_private=0x7fffa9901760) at
../../source3/lib/g_lock.c:1267
#10 0x00007fc04b1bfe1c in _share_mode_entry_prepare_lock
(prepare_state=0x7fffa9901960, id=..., servicepath=0x0, smb_fname=0x0,
old_write_time=0x0, fn=0x7fc04b21c0b5 <close_share_mode_lock_prepare>,
private_data=0x7fffa9901960, location=0x7fc04b32e5a8
"../../source3/smbd/close.c:451") at
../../source3/locking/share_mode_lock.c:3022
#11 0x00007fc04b21c99b in close_remove_share_mode (fsp=0x565379152c80,
close_type=NORMAL_CLOSE) at ../../source3/smbd/close.c:451
#12 0x00007fc04b21dcf2 in close_normal_file (req=0x5653790ce430,
fsp=0x565379152c80, close_type=NORMAL_CLOSE) at
../../source3/smbd/close.c:910
#13 0x00007fc04b22061c in close_file_smb (req=0x5653790ce430,
fsp=0x565379152c80, close_type=NORMAL_CLOSE) at
../../source3/smbd/close.c:1663
#14 0x00007fc04b270e67 in smbd_smb2_close (req=0x5653790964c0,
_fsp=0x5653790bbd08, in_flags=0, out_flags=0x5653790bbd12,
out_creation_ts=0x5653790bbd18, out_last_access_ts=0x5653790bbd28,
out_last_write_ts=0x5653790bbd38, out_change_ts=0x5653790bbd48,
out_allocation_size=0x5653790bbd58, out_end_of_file=0x5653790bbd60,
out_file_attributes=0x5653790bbd68) at ../../source3/smbd/smb2_close.c:224
#15 0x00007fc04b271214 in smbd_smb2_close_send (mem_ctx=0x5653790964c0,
ev=0x565379019a60, smb2req=0x5653790964c0, in_fsp=0x565379152c80,
in_flags=0) at ../../source3/smbd/smb2_close.c:335
#16 0x00007fc04b2705fb in smbd_smb2_request_process_close
(req=0x5653790964c0) at ../../source3/smbd/smb2_close.c:72
#17 0x00007fc04b25c567 in smbd_smb2_request_dispatch
(req=0x5653790964c0) at ../../source3/smbd/smb2_server.c:3405
while without vfs_recycle() it is like this:
Hardware watchpoint 2: share_mode_lock_key_refcount
Old value = 0
New value = 1
get_share_mode_lock_internal (id=..., servicepath=0x0, smb_fname=0x0,
old_write_time=0x0, lck=0x561513496800) at
../../source3/locking/share_mode_lock.c:972
972 if (static_share_mode_data != NULL) {
(gdb) bt
#0 get_share_mode_lock_internal (id=..., servicepath=0x0,
smb_fname=0x0, old_write_time=0x0, lck=0x561513496800) at
../../source3/locking/share_mode_lock.c:972
#1 0x00007f294011e921 in get_existing_share_mode_lock
(mem_ctx=0x561513499000, id=...) at
../../source3/locking/share_mode_lock.c:1084
#2 0x00007f29401ea153 in smbd_smb2_setinfo_send
(mem_ctx=0x561513499000, ev=0x56151335da60, smb2req=0x561513499000,
fsp=0x56151348bac0, in_info_type=1 '\001', in_file_info_class=10 '\n',
in_input_buffer=...,
in_additional_information=0) at ../../source3/smbd/smb2_setinfo.c:482
#3 0x00007f29401e9202 in smbd_smb2_request_process_setinfo
(req=0x561513499000) at ../../source3/smbd/smb2_setinfo.c:112
#4 0x00007f29401c1b96 in smbd_smb2_request_dispatch
(req=0x561513499000) at ../../source3/smbd/smb2_server.c:3482
Hardware watchpoint 2: share_mode_lock_key_refcount
Old value = 1
New value = 2
get_share_mode_lock_internal (id=..., servicepath=0x0, smb_fname=0x0,
old_write_time=0x0, lck=0x7ffe5b82bc10) at
../../source3/locking/share_mode_lock.c:972
972 if (static_share_mode_data != NULL) {
(gdb) bt
#0 get_share_mode_lock_internal (id=..., servicepath=0x0,
smb_fname=0x0, old_write_time=0x0, lck=0x7ffe5b82bc10) at
../../source3/locking/share_mode_lock.c:972
#1 0x00007f294012435b in share_mode_do_locked_vfs_denied_fn (glck=0x0,
cb_private=0x7ffe5b82bcb0) at ../../source3/locking/share_mode_lock.c:2793
#2 0x00007f294012470f in _share_mode_do_locked_vfs_denied (id=...,
fn=0x7f2940113b7b <file_has_open_streams_locked>,
private_data=0x7ffe5b82bd3e, location=0x7f2940270798
"../../source3/locking/locking.c:1259")
at ../../source3/locking/share_mode_lock.c:2875
#3 0x00007f2940113c0f in file_has_open_streams (fsp=0x56151348bac0) at
../../source3/locking/locking.c:1259
#4 0x00007f294014ed2f in rename_internals_fsp (conn=0x5615134184d0,
fsp=0x56151348bac0, dst_dirfsp=0x0, smb_fname_dst_in=0x5615134262d0,
dst_original_lcomp=0x561513426470 "QQQ08b", attrs=6,
replace_if_exists=false) at ../../source3/smbd/smb2_reply.c:1437
#5 0x00007f2940163be8 in smb2_file_rename_information
(conn=0x5615134184d0, req=0x56151341cbe0, pdata=0x5615134a8530 "",
total_data=40, fsp=0x56151348bac0, smb_fname_src=0x561513496a10)
at ../../source3/smbd/smb2_trans2.c:5042
#6 0x00007f2940167fe5 in smbd_do_setfilepathinfo (conn=0x5615134184d0,
req=0x56151341cbe0, mem_ctx=0x56151348e100, info_level=65290,
fsp=0x56151348bac0, smb_fname=0x561513496a10, ppdata=0x7ffe5b82c0c8,
total_data=40, ret_data_size=0x7ffe5b82c0c4) at
../../source3/smbd/smb2_trans2.c:6990
#7 0x00007f29401ea2dc in smbd_smb2_setinfo_send
(mem_ctx=0x561513499000, ev=0x56151335da60, smb2req=0x561513499000,
fsp=0x56151348bac0, in_info_type=1 '\001', in_file_info_class=10 '\n',
in_input_buffer=...,
in_additional_information=0) at ../../source3/smbd/smb2_setinfo.c:513
#8 0x00007f29401e9202 in smbd_smb2_request_process_setinfo
(req=0x561513499000) at ../../source3/smbd/smb2_setinfo.c:112
#9 0x00007f29401c1b96 in smbd_smb2_request_dispatch
(req=0x561513499000) at ../../source3/smbd/smb2_server.c:3482
Hardware watchpoint 2: share_mode_lock_key_refcount
Old value = 2
New value = 1
put_share_mode_lock_internal (lck=0x7ffe5b82bc10) at
../../source3/locking/share_mode_lock.c:1020
1020 if (share_mode_lock_key_refcount > 0) {
(gdb) bt
#0 put_share_mode_lock_internal (lck=0x7ffe5b82bc10) at
../../source3/locking/share_mode_lock.c:1020
#1 0x00007f29401244b9 in share_mode_do_locked_vfs_denied_fn (glck=0x0,
cb_private=0x7ffe5b82bcb0) at ../../source3/locking/share_mode_lock.c:2813
#2 0x00007f294012470f in _share_mode_do_locked_vfs_denied (id=...,
fn=0x7f2940113b7b <file_has_open_streams_locked>,
private_data=0x7ffe5b82bd3e, location=0x7f2940270798
"../../source3/locking/locking.c:1259")
at ../../source3/locking/share_mode_lock.c:2875
#3 0x00007f2940113c0f in file_has_open_streams (fsp=0x56151348bac0) at
../../source3/locking/locking.c:1259
#4 0x00007f294014ed2f in rename_internals_fsp (conn=0x5615134184d0,
fsp=0x56151348bac0, dst_dirfsp=0x0, smb_fname_dst_in=0x5615134262d0,
dst_original_lcomp=0x561513426470 "QQQ08b", attrs=6,
replace_if_exists=false) at ../../source3/smbd/smb2_reply.c:1437
#5 0x00007f2940163be8 in smb2_file_rename_information
(conn=0x5615134184d0, req=0x56151341cbe0, pdata=0x5615134a8530 "",
total_data=40, fsp=0x56151348bac0, smb_fname_src=0x561513496a10)
at ../../source3/smbd/smb2_trans2.c:5042
#6 0x00007f2940167fe5 in smbd_do_setfilepathinfo (conn=0x5615134184d0,
req=0x56151341cbe0, mem_ctx=0x56151348e100, info_level=65290,
fsp=0x56151348bac0, smb_fname=0x561513496a10, ppdata=0x7ffe5b82c0c8,
total_data=40, ret_data_size=0x7ffe5b82c0c4) at
../../source3/smbd/smb2_trans2.c:6990
#7 0x00007f29401ea2dc in smbd_smb2_setinfo_send
(mem_ctx=0x561513499000, ev=0x56151335da60, smb2req=0x561513499000,
fsp=0x56151348bac0, in_info_type=1 '\001', in_file_info_class=10 '\n',
in_input_buffer=...,
in_additional_information=0) at ../../source3/smbd/smb2_setinfo.c:513
#8 0x00007f29401e9202 in smbd_smb2_request_process_setinfo
(req=0x561513499000) at ../../source3/smbd/smb2_setinfo.c:112
#9 0x00007f29401c1b96 in smbd_smb2_request_dispatch
(req=0x561513499000) at ../../source3/smbd/smb2_server.c:3482
Hardware watchpoint 2: share_mode_lock_key_refcount
Old value = 1
New value = 2
get_share_mode_lock_internal (id=..., servicepath=0x0, smb_fname=0x0,
old_write_time=0x0, lck=0x5615134a9010) at
../../source3/locking/share_mode_lock.c:972
972 if (static_share_mode_data != NULL) {
(gdb) bt
#0 get_share_mode_lock_internal (id=..., servicepath=0x0,
smb_fname=0x0, old_write_time=0x0, lck=0x5615134a9010) at
../../source3/locking/share_mode_lock.c:972
#1 0x00007f294011e921 in get_existing_share_mode_lock
(mem_ctx=0x561513425150, id=...) at
../../source3/locking/share_mode_lock.c:1084
#2 0x00007f294014fd35 in rename_internals_fsp (conn=0x5615134184d0,
fsp=0x56151348bac0, dst_dirfsp=0x0, smb_fname_dst_in=0x5615134262d0,
dst_original_lcomp=0x561513426470 "QQQ08b", attrs=6,
replace_if_exists=false) at ../../source3/smbd/smb2_reply.c:1740
#3 0x00007f2940163be8 in smb2_file_rename_information
(conn=0x5615134184d0, req=0x56151341cbe0, pdata=0x5615134a8530 "",
total_data=40, fsp=0x56151348bac0, smb_fname_src=0x561513496a10)
at ../../source3/smbd/smb2_trans2.c:5042
#4 0x00007f2940167fe5 in smbd_do_setfilepathinfo (conn=0x5615134184d0,
req=0x56151341cbe0, mem_ctx=0x56151348e100, info_level=65290,
fsp=0x56151348bac0, smb_fname=0x561513496a10, ppdata=0x7ffe5b82c0c8,
total_data=40, ret_data_size=0x7ffe5b82c0c4) at
../../source3/smbd/smb2_trans2.c:6990
#5 0x00007f29401ea2dc in smbd_smb2_setinfo_send
(mem_ctx=0x561513499000, ev=0x56151335da60, smb2req=0x561513499000,
fsp=0x56151348bac0, in_info_type=1 '\001', in_file_info_class=10 '\n',
in_input_buffer=...,
in_additional_information=0) at ../../source3/smbd/smb2_setinfo.c:513
#6 0x00007f29401e9202 in smbd_smb2_request_process_setinfo
(req=0x561513499000) at ../../source3/smbd/smb2_setinfo.c:112
#7 0x00007f29401c1b96 in smbd_smb2_request_dispatch
(req=0x561513499000) at ../../source3/smbd/smb2_server.c:3482
and the panic:
#0 __pthread_kill_implementation (threadid=<optimized out>,
signo=signo at entry=6, no_tid=no_tid at entry=0) at pthread_kill.c:44
#1 0x00007f293fb1ccb3 in __pthread_kill_internal (signo=6,
threadid=<optimized out>) at pthread_kill.c:78
#2 0x00007f293facc9c6 in __GI_raise (sig=sig at entry=6) at
../sysdeps/posix/raise.c:26
#3 0x00007f293fab67f4 in __GI_abort () at abort.c:79
#4 0x00007f293ffdbbfa in dump_core () at ../../source3/lib/dumpcore.c:338
#5 0x00007f293ffed661 in smb_panic_s3 (why=0x7f2940276e08 "assert
failed: share_mode_lock_key_refcount == 0") at ../../source3/lib/util.c:713
#6 0x00007f293fce19a1 in smb_panic (why=0x7f2940276e08 "assert failed:
share_mode_lock_key_refcount == 0") at ../../lib/util/fault.c:198
#7 0x00007f2940124d7a in _share_mode_entry_prepare_lock
(prepare_state=0x7ffe5b82b610, id=..., servicepath=0x561513488970
"/home/pfilipen/workspace/projects/samba/2571/st/ad_member/share",
smb_fname=0x5615134a8880, old_write_time=0x7ffe5b82b560,
fn=0x7f2940179986 <open_ntcreate_lock_add_entry>,
private_data=0x7ffe5b82b610, location=0x7f2940291830
"../../source3/smbd/open.c:4342")
at ../../source3/locking/share_mode_lock.c:3010
#8 0x00007f294017aec1 in open_file_ntcreate (conn=0x5615134184d0,
req=0x0, access_mask=137, share_access=7, create_disposition=1,
create_options=0, new_dos_attributes=0, oplock_request=8, lease=0x0,
private_flags=0, parent_dir_fname=0x561513430540,
smb_fname_atname=0x5615134aa040, pinfo=0x7ffe5b82b7cc,
fsp=0x5615134a5d00) at ../../source3/smbd/open.c:4342
#9 0x00007f294017fdad in create_file_unixpath (conn=0x5615134184d0,
req=0x0, dirfsp=0x5615134a9b10, smb_fname=0x5615134a5aa0,
access_mask=137, share_access=7, create_disposition=1, create_options=0,
file_attributes=128, oplock_request=8, lease=0x0,
allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0,
result=0x7ffe5b82b990, pinfo=0x7ffe5b82b99c) at
../../source3/smbd/open.c:6337
#10 0x00007f2940180993 in create_file_default (conn=0x5615134184d0,
req=0x0, dirfsp=0x5615134a9b10, smb_fname=0x5615134a5aa0,
access_mask=137, share_access=7, create_disposition=1, create_options=0,
file_attributes=128, oplock_request=0, lease=0x0,
allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0,
result=0x7ffe5b82bbf8, pinfo=0x7ffe5b82bbec, in_context_blobs=0x0,
out_context_blobs=0x0)
at ../../source3/smbd/open.c:6656
#11 0x00007f2940130932 in vfswrap_create_file (handle=0x561513496dc0,
req=0x0, dirfsp=0x5615134a9b10, smb_fname=0x5615134a5aa0,
access_mask=137, share_access=7, create_disposition=1, create_options=0,
file_attributes=128, oplock_request=0, lease=0x0,
allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0,
result=0x7ffe5b82bbf8, pinfo=0x7ffe5b82bbec, in_context_blobs=0x0,
out_context_blobs=0x0)
at ../../source3/modules/vfs_default.c:827
#12 0x00007f294018d328 in smb_vfs_call_create_file
(handle=0x561513496dc0, req=0x0, dirfsp=0x5615134a9b10,
smb_fname=0x5615134a5aa0, access_mask=137, share_access=7,
create_disposition=1, create_options=0,
file_attributes=128, oplock_request=0, lease=0x0,
allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0,
result=0x7ffe5b82bbf8, pinfo=0x7ffe5b82bbec, in_context_blobs=0x0,
out_context_blobs=0x0)
at ../../source3/smbd/vfs.c:1576
#13 0x00007f2940149b77 in copy_internals (ctx=0x561513425150,
conn=0x5615134184d0, req=0x0, src_dirfsp=0x5615134a9b10,
smb_fname_src=0x5615134a5aa0, dst_dirfsp=0x5615134a69d0,
smb_fname_dst=0x5615134a90c0,
attrs=6) at ../../source3/smbd/smb2_nttrans.c:248
#14 0x00007f292b549060 in copy_reg (handle=0x56151348adb0,
srcfsp=0x5615134a9b10, source=0x561513cb64b0, dstfsp=0x5615134a69d0,
dest=0x56151342bc80) at ../../source3/modules/vfs_crossrename.c:116
#15 0x00007f292b5491aa in crossrename_renameat (handle=0x56151348adb0,
srcfsp=0x5615134a9b10, smb_fname_src=0x561513cb64b0,
dstfsp=0x5615134a69d0, smb_fname_dst=0x56151342bc80)
at ../../source3/modules/vfs_crossrename.c:167
#16 0x00007f294018e176 in smb_vfs_call_renameat (handle=0x56151348adb0,
srcfsp=0x5615134a9b10, smb_fname_src=0x561513cb64b0,
dstfsp=0x5615134a69d0, smb_fname_dst=0x56151342bc80) at
../../source3/smbd/vfs.c:1775
#17 0x00007f294014fe00 in rename_internals_fsp (conn=0x5615134184d0,
fsp=0x56151348bac0, dst_dirfsp=0x0, smb_fname_dst_in=0x5615134262d0,
dst_original_lcomp=0x561513426470 "QQQ08b", attrs=6,
replace_if_exists=false) at ../../source3/smbd/smb2_reply.c:1749
#18 0x00007f2940163be8 in smb2_file_rename_information
(conn=0x5615134184d0, req=0x56151341cbe0, pdata=0x5615134a8530 "",
total_data=40, fsp=0x56151348bac0, smb_fname_src=0x561513496a10)
at ../../source3/smbd/smb2_trans2.c:5042
#19 0x00007f2940167fe5 in smbd_do_setfilepathinfo (conn=0x5615134184d0,
req=0x56151341cbe0, mem_ctx=0x56151348e100, info_level=65290,
fsp=0x56151348bac0, smb_fname=0x561513496a10, ppdata=0x7ffe5b82c0c8,
total_data=40, ret_data_size=0x7ffe5b82c0c4) at
../../source3/smbd/smb2_trans2.c:6990
#20 0x00007f29401ea2dc in smbd_smb2_setinfo_send
(mem_ctx=0x561513499000, ev=0x56151335da60, smb2req=0x561513499000,
fsp=0x56151348bac0, in_info_type=1 '\001', in_file_info_class=10 '\n',
in_input_buffer=...,
in_additional_information=0) at ../../source3/smbd/smb2_setinfo.c:513
#21 0x00007f29401e9202 in smbd_smb2_request_process_setinfo
(req=0x561513499000) at ../../source3/smbd/smb2_setinfo.c:112
#22 0x00007f29401c1b96 in smbd_smb2_request_dispatch
(req=0x561513499000) at ../../source3/smbd/smb2_server.c:3482
So we really need to address this.
On 10/6/22 19:55, Jeremy Allison wrote:
> On Thu, Oct 06, 2022 at 10:40:57AM -0400, Andrew Walker via
> samba-technical wrote:
>> On Thu, Oct 6, 2022 at 10:28 AM Pavel Filipenský via samba-technical <
>> samba-technical at lists.samba.org> wrote:
>>
>>> Hi,
>>>
>>> I am working on a fix for RH bugzillahttps://
>>> bugzilla.redhat.com/show_bug.cgi?id=2125339
>>>
>>> If the share is using vfs_recycle and vfs_crossrename modules and the
>>> recycle repo is on a different filesystem, like here:
>>>
>>> vfs objects = recycle crossrename
>>> recycle:repository = /different_filesystem/
>>>
>>> The deleted file should be moved to /different_filesystem/recycle,
>>> but it
>>> fails. Since this is a different fs, we cannot use
>>>
>>> rename("File", "/different_filesystem/recycle/File")
>>>
>>> but instead samba code uses two syscalls:
>>>
>>> unlink("/different_filesystem/recycle/File")
>>> openat(AT_FDCWD, "/different_filesystem/recycle/File", O_CREAT, 0600)
>>>
>>> Normally, the destination file "/different_filesystem/recycle/File"
>>> does
>>> not exist and unlink() fails with ENOENT. This is correctly handled in
>>> samba-4.12:
>>>
>>>
>>> 51 static int copy_reg(const char *source, const char *dest)
>>> 52 {
>>> ...
>>> 76 »···if (unlink (dest) && errno != ENOENT) {
>>> 77 »···»···close(ifd);
>>> 78 »···»···return -1;
>>> 79 »···}
>>>
>>> But newer versions of samba miss the check for ENOENT and the operation
>>> fails, doing map_nt_error_from_unix(errno). I have tried to the same
>>> fix,
>>> and added to copy_reg() this:
>>>
>>> - if (ret == -1) {
>>> + if (ret == -1 && errno != ENOENT) {
>>> status = map_nt_error_from_unix(errno);
>>> goto out;
>>> }
>>>
>>> Unfortunately, it does not work. It causes this panic:
>>>
>>>
>>>
>>> Program received signal SIGABRT, Aborted.
>>> __pthread_kill_implementation (threadid=<optimized out>,
>>> signo=signo at entry=6,
>>> no_tid=no_tid at entry=0) at pthread_kill.c:44
>>> 44»· return INTERNAL_SYSCALL_ERROR_P (ret) ?
>>> INTERNAL_SYSCALL_ERRNO
>>> (ret) : 0;
>>> #0 __pthread_kill_implementation (threadid=<optimized out>,
>>> signo=signo at entry=6, no_tid=no_tid at entry=0) at pthread_kill.c:44
>>> #1 0x00007fc04abb7cb3 in __pthread_kill_internal (signo=6,
>>> threadid=<optimized out>) at pthread_kill.c:78
>>> #2 0x00007fc04ab679c6 in __GI_raise (sig=sig at entry=6) at
>>> ../sysdeps/posix/raise.c:26
>>> #3 0x00007fc04ab517f4 in __GI_abort () at abort.c:79
>>> #4 0x00007fc04b076bfa in dump_core () at
>>> ../../source3/lib/dumpcore.c:338
>>> #5 0x00007fc04b088661 in smb_panic_s3 (why=0x7fc04b311928 "assert
>>> failed:
>>> share_mode_lock_key_refcount == 0") at ../../source3/lib/util.c:713
>>> #6 0x00007fc04ad7c9a1 in smb_panic (why=0x7fc04b311928 "assert failed:
>>> share_mode_lock_key_refcount == 0") at ../../lib/util/fault.c:198
>>> #7 0x00007fc04b1bfd7a in _share_mode_entry_prepare_lock
>>> (prepare_state=0x7fffa9900f60, id=..., servicepath=0x565379144e10
>>> "/home/pfilipen/workspace/projects/samba/2571/st/ad_member/share",
>>> smb_fname=0x565379162da0, old_write_time=0x7fffa9900eb0,
>>> fn=0x7fc04b2145d9 <open_ntcreate_lock_add_entry>,
>>> private_data=0x7fffa9900f60, location=0x7fc04b32c0f0
>>> "../../source3/smbd/open.c:4342")
>>> at ../../source3/locking/share_mode_lock.c:3010
>>> #8 0x00007fc04b215b14 in open_file_ntcreate (conn=0x5653790d46b0,
>>> req=0x0, access_mask=137, share_access=7, create_disposition=1,
>>> create_options=0, new_dos_attributes=0, oplock_request=8, lease=0x0,
>>> private_flags=0, parent_dir_fname=0x5653790019b0,
>>> smb_fname_atname=0x565379156ec0, pinfo=0x7fffa990111c,
>>> fsp=0x565379162bc0)
>>> at ../../source3/smbd/open.c:4342
>>> #9 0x00007fc04b21a8c8 in create_file_unixpath (conn=0x5653790d46b0,
>>> req=0x0, dirfsp=0x56537905a9d0, smb_fname=0x5653791497d0,
>>> access_mask=137,
>>> share_access=7, create_disposition=1, create_options=0,
>>> file_attributes=128, oplock_request=8, lease=0x0,
>>> allocation_size=0,
>>> private_flags=0, sd=0x0, ea_list=0x0, result=0x7fffa99012e0,
>>> pinfo=0x7fffa99012ec) at ../../source3/smbd/open.c:6337
>>> #10 0x00007fc04b21b4ae in create_file_default (conn=0x5653790d46b0,
>>> req=0x0, dirfsp=0x56537905a9d0, smb_fname=0x5653791497d0,
>>> access_mask=137,
>>> share_access=7, create_disposition=1, create_options=0,
>>> file_attributes=128, oplock_request=0, lease=0x0,
>>> allocation_size=0,
>>> private_flags=0, sd=0x0, ea_list=0x0, result=0x7fffa9901548,
>>> pinfo=0x7fffa990153c, in_context_blobs=0x0, out_context_blobs=0x0)
>>> at ../../source3/smbd/open.c:6656
>>> #11 0x00007fc04b1cb932 in vfswrap_create_file (handle=0x565379152be0,
>>> req=0x0, dirfsp=0x56537905a9d0, smb_fname=0x5653791497d0,
>>> access_mask=137,
>>> share_access=7, create_disposition=1, create_options=0,
>>> file_attributes=128, oplock_request=0, lease=0x0,
>>> allocation_size=0,
>>> private_flags=0, sd=0x0, ea_list=0x0, result=0x7fffa9901548,
>>> pinfo=0x7fffa990153c, in_context_blobs=0x0, out_context_blobs=0x0)
>>> at ../../source3/modules/vfs_default.c:827
>>> #12 0x00007fc04b227e43 in smb_vfs_call_create_file
>>> (handle=0x565379152be0,
>>> req=0x0, dirfsp=0x56537905a9d0, smb_fname=0x5653791497d0,
>>> access_mask=137,
>>> share_access=7, create_disposition=1, create_options=0,
>>> file_attributes=128, oplock_request=0, lease=0x0,
>>> allocation_size=0,
>>> private_flags=0, sd=0x0, ea_list=0x0, result=0x7fffa9901548,
>>> pinfo=0x7fffa990153c, in_context_blobs=0x0, out_context_blobs=0x0)
>>> at ../../source3/smbd/vfs.c:1576
>>> #13 0x00007fc04b1e4b77 in copy_internals (ctx=0x5653790e1330,
>>> conn=0x5653790d46b0, req=0x0, src_dirfsp=0x56537905a9d0,
>>> smb_fname_src=0x5653791497d0, dst_dirfsp=0x5653790d4aa0,
>>> smb_fname_dst=0x565379162700,
>>> attrs=6) at ../../source3/smbd/smb2_nttrans.c:248
>>> #14 0x00007fc0365e4060 in copy_reg (handle=0x565379148050,
>>> srcfsp=0x56537905a9d0, source=0x565379155650, dstfsp=0x5653790d4aa0,
>>> dest=0x5653790e28e0) at ../../source3/modules/vfs_crossrename.c:115
>>> #15 0x00007fc0365e41aa in crossrename_renameat (handle=0x565379148050,
>>> srcfsp=0x56537905a9d0, smb_fname_src=0x565379155650,
>>> dstfsp=0x5653790d4aa0,
>>> smb_fname_dst=0x5653790e28e0)
>>> at ../../source3/modules/vfs_crossrename.c:166
>>> #16 0x00007fc04b228c91 in smb_vfs_call_renameat (handle=0x565379148050,
>>> srcfsp=0x56537905a9d0, smb_fname_src=0x565379155650,
>>> dstfsp=0x5653790d4aa0,
>>> smb_fname_dst=0x5653790e28e0) at ../../source3/smbd/vfs.c:1775
>>> #17 0x00007fc0365ded2f in recycle_unlink_internal
>>> (handle=0x565379148680,
>>> dirfsp=0x56537905a9d0, smb_fname=0x565379155650, flags=0) at
>>> ../../source3/modules/vfs_recycle.c:690
>>> #18 0x00007fc0365defaa in recycle_unlinkat (handle=0x565379148680,
>>> dirfsp=0x56537905a9d0, smb_fname=0x565379155650, flags=0) at
>>> ../../source3/modules/vfs_recycle.c:735
>>> #19 0x00007fc04b2296fe in smb_vfs_call_unlinkat (handle=0x565379148680,
>>> dirfsp=0x56537905a9d0, smb_fname=0x565379155650, flags=0) at
>>> ../../source3/smbd/vfs.c:1932
>>> #20 0x00007fc04b21d106 in close_remove_share_mode (fsp=0x565379152c80,
>>> close_type=NORMAL_CLOSE) at ../../source3/smbd/close.c:581
>>> #21 0x00007fc04b21dcf2 in close_normal_file (req=0x5653790ce430,
>>> fsp=0x565379152c80, close_type=NORMAL_CLOSE) at
>>> ../../source3/smbd/close.c:910
>>> #22 0x00007fc04b22061c in close_file_smb (req=0x5653790ce430,
>>> fsp=0x565379152c80, close_type=NORMAL_CLOSE) at
>>> ../../source3/smbd/close.c:1663
>>>
>>>
>>> The cause of the panic is "assert failed:
>>> share_mode_lock_key_refcount ==
>>> 0" in source3/locking/share_mode_lock.c:3010
>>> The share_mode_lock_key_refcount is already 1, the first reference is
>>> taken here:
>>>
>>> Hardware watchpoint 2: share_mode_lock_key_refcount
>>> Old value = 0
>>> New value = 1
>>> get_share_mode_lock_internal (id=..., servicepath=0x0, smb_fname=0x0,
>>> old_write_time=0x0, lck=0x7fffa9901980) at
>>> ../../source3/locking/share_mode_lock.c:972
>>> 972»»···if (static_share_mode_data != NULL) {
>>> #0 get_share_mode_lock_internal (id=..., servicepath=0x0,
>>> smb_fname=0x0,
>>> old_write_time=0x0, lck=0x7fffa9901980) at
>>> ../../source3/locking/share_mode_lock.c:972
>>> #1 0x00007fc04b1bfa24 in share_mode_entry_prepare_lock_fn
>>> (glck=0x7fffa9901190, cb_private=0x7fffa9901760) at
>>> ../../source3/locking/share_mode_lock.c:2952
>>> #2 0x00007fc04b05c7d2 in g_lock_lock_cb_run_and_store
>>> (cb_state=0x7fffa9901190) at ../../source3/lib/g_lock.c:597
>>> #3 0x00007fc04b05e8c1 in g_lock_lock_simple_fn (rec=0x7fffa99014a0,
>>> value=..., private_data=0x7fffa9901630) at
>>> ../../source3/lib/g_lock.c:1212
>>> #4 0x00007fc04b05833d in dbwrap_watched_do_locked_fn
>>> (backend_rec=0x7fffa9901350, backend_value=...,
>>> private_data=0x7fffa9901470) at
>>> ../../source3/lib/dbwrap/dbwrap_watch.c:458
>>> #5 0x00007fc04aa33e44 in db_tdb_do_locked (db=0x5653790ca050, key=...,
>>> fn=0x7fc04b0582ab <dbwrap_watched_do_locked_fn>,
>>> private_data=0x7fffa9901470) at ../../lib/dbwrap/dbwrap_tdb.c:208
>>> #6 0x00007fc04aa304db in dbwrap_do_locked (db=0x5653790ca050, key=...,
>>> fn=0x7fc04b0582ab <dbwrap_watched_do_locked_fn>,
>>> private_data=0x7fffa9901470) at ../../lib/dbwrap/dbwrap.c:553
>>> #7 0x00007fc04b058435 in dbwrap_watched_do_locked (db=0x5653790cf910,
>>> key=..., fn=0x7fc04b05e4fa <g_lock_lock_simple_fn>,
>>> private_data=0x7fffa9901630) at
>>> ../../source3/lib/dbwrap/dbwrap_watch.c:480
>>> #8 0x00007fc04aa304db in dbwrap_do_locked (db=0x5653790cf910, key=...,
>>> fn=0x7fc04b05e4fa <g_lock_lock_simple_fn>,
>>> private_data=0x7fffa9901630) at
>>> ../../lib/dbwrap/dbwrap.c:553
>>> #9 0x00007fc04b05eb28 in g_lock_lock (ctx=0x565379020280, key=...,
>>> type=G_LOCK_WRITE, timeout=..., cb_fn=0x7fc04b1bf90d
>>> <share_mode_entry_prepare_lock_fn>, cb_private=0x7fffa9901760) at
>>> ../../source3/lib/g_loc…
>>> #10 0x00007fc04b1bfe1c in _share_mode_entry_prepare_lock
>>> (prepare_state=0x7fffa9901960, id=..., servicepath=0x0, smb_fname=0x0,
>>> old_write_time=0x0, fn=0x7fc04b21c0b5 <close_share_mode_lock_prepare>,
>>> private_dat…
>>> #11 0x00007fc04b21c99b in close_remove_share_mode (fsp=0x565379152c80,
>>> close_type=NORMAL_CLOSE) at ../../source3/smbd/close.c:451
>>> #12 0x00007fc04b21dcf2 in close_normal_file (req=0x5653790ce430,
>>> fsp=0x565379152c80, close_type=NORMAL_CLOSE) at
>>> ../../source3/smbd/close.c:910
>>> #13 0x00007fc04b22061c in close_file_smb (req=0x5653790ce430,
>>> fsp=0x565379152c80, close_type=NORMAL_CLOSE) at
>>> ../../source3/smbd/close.c:1663
>>>
>>>
>>> So the issue comes from the logic in close_remove_share_mode()
>>>
>>> static NTSTATUS close_remove_share_mode(files_struct *fsp, enum
>>> file_close_type close_type)
>>> {
>>> status =
>>> share_mode_entry_prepare_lock_del(&lck_state.prepare_state,
>>>
>>> ret = SMB_VFS_UNLINKAT(conn,
>>>
>>> ulstatus =
>>> share_mode_entry_prepare_unlock(&lck_state.prepare_state,
>>> }
>>>
>>> Each process can hold just one share_mode_lock_key_refcount, but
>>> here we
>>> have two nested calls, both grabbing share_mode_lock_key_refcount:
>>> 1. share_mode_entry_prepare_lock_del()
>>> 2. SMB_VFS_UNLINKAT() -> recycle_unlink_internal() ->
>>> crossrename_renameat() -> open_file_ntcreate() ->
>>> _share_mode_entry_prepare_lock()
>>>
>>>
>>>
>>> How this should be fixed? Can we remove the assert and allow to grab
>>> the
>>> share_mode_lock_key_refcount
>>> again give the owner is the process itself?
>>>
>>>
>>> Thanks,
>>> Pavel
>>>
>>
>> Perhaps instead of layering the recyclebin over vfs_crossrename, we
>> should
>> generate separate recyclebins at filesystem mountpoints when the SMB
>> share contains nested ones?
>>
>> This would preserve atomicity of the rename operation and would avoid
>> exposing users to limits of vfs_crossrename (e.g. purging of files that
>> exceed the cross-rename limit -- which is a pretty significant POLA
>> violation).
>>
>> If we want to go this route, I can make a merge request to add it
>> (since I
>> already have POC code to do this).
>
> That sounds like a plan to me ! Can we see the MR request ?
More information about the samba-technical
mailing list