From: Matthias Grandl Date: Fri, 10 Jul 2026 05:58:42 +0000 (+0200) Subject: vfs_ceph_snapshots: Fix panic on snapshot access with a "/"-rooted share X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=abb48aacbd994877006bf9156e633d3cf29a34bc;p=thirdparty%2Fsamba.git vfs_ceph_snapshots: Fix panic on snapshot access with a "/"-rooted share ceph_snap_gmt_convert_dir() builds an absolute snapshot path by joining the share's connectpath, the request-relative name and the snapshot subdir with '/' separators, then hands it to OpenDir(). OpenDir() -> fd_openat() -> filename_convert_dirfsp_rel() splits the path on '/' and openat_pathref_fsp_nosymlink() asserts that no component is empty: SMB_ASSERT(rel_fname.base_name[0] != '\0') source3/smbd/files.c:1212 connectpath is a bare "/" when the share is mounted at the file system root, so the join yields a leading "//" (e.g. "//.snap" or "//dir/.snap"). That empty first component trips the assert and panics smbd as soon as a snapshot is accessed. Whether the malformed path actually reaches the assert also depends on the Ceph client accepting a non-canonical "//" path in the preceding stat(), so the panic is libcephfs-version dependent. Canonicalize the .snap directory path with canonicalize_absolute_path() after building it, so the path handed to OpenDir() is always canonical and the empty leading component can no longer occur. BUG: https://bugzilla.samba.org/show_bug.cgi?id=16176 Signed-off-by: Matthias Grandl Reviewed-by: Anoop C S Reviewed-by: David Disseldorp ddiss@samba.org Autobuild-User(master): Anoop C S Autobuild-Date(master): Tue Jul 21 16:12:18 UTC 2026 on atb-devel-224 --- diff --git a/source3/modules/vfs_ceph_snapshots.c b/source3/modules/vfs_ceph_snapshots.c index cf2dfdc2d5d..203b907b90b 100644 --- a/source3/modules/vfs_ceph_snapshots.c +++ b/source3/modules/vfs_ceph_snapshots.c @@ -29,6 +29,7 @@ #include "lib/util/tevent_ntstatus.h" #include "lib/util/smb_strtox.h" #include "source3/smbd/dir.h" +#include "lib/util_path.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS @@ -505,6 +506,7 @@ static int ceph_snap_gmt_convert_dir(struct vfs_handle_struct *handle, size_t buflen) { int ret; + char *canon = NULL; NTSTATUS status; struct smb_Dir *dir_hnd = NULL; struct files_struct *dirfsp = NULL; @@ -537,6 +539,19 @@ static int ceph_snap_gmt_convert_dir(struct vfs_handle_struct *handle, goto err_out; } + /* + * Canonicalize to collapse any "//" run when connectpath + * is a bare "/", which would trip the SMB_ASSERT in + * openat_pathref_fsp_nosymlink(). + */ + canon = canonicalize_absolute_path(tmp_ctx, _converted_buf); + if (canon == NULL) { + ret = -ENOMEM; + goto err_out; + } + strlcpy(_converted_buf, canon, buflen); + TALLOC_FREE(canon); + snaps_dname = synthetic_smb_fname(tmp_ctx, _converted_buf, NULL,