Bug 16222 - vfs_ceph_new mishandles absolute root pathrefs and can crash in ceph_ll_lookup
Summary: vfs_ceph_new mishandles absolute root pathrefs and can crash in ceph_ll_lookup
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: VFS Modules (show other bugs)
Version: 4.24.4
Hardware: All Linux
: P5 critical (vote)
Target Milestone: ---
Assignee: Samba QA Contact
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2026-08-18 13:59 UTC by matthias.grandl@croit.io
Modified: 2026-08-18 13:59 UTC (History)
0 users

See Also:


Attachments
Proposed fix for synthetic absolute-root pathref handling. (4.39 KB, application/mbox)
2026-08-18 13:59 UTC, matthias.grandl@croit.io
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description matthias.grandl@croit.io 2026-08-18 13:59:35 UTC
Created attachment 19170 [details]
Proposed fix for synthetic absolute-root pathref handling.

smbd segfaults while vfs_ceph_snapshots resolves an advertised @GMT path
on a share using the vfs_ceph_new backend.

This is reproducible with Samba 4.24.4. The package already contains the
backport for bug 16176, so this is not the consecutive-slash assertion fixed
there.

The crash happens because vfs_ceph_new does not correctly handle the
synthetic filesystem-root pathref that Samba constructs while resolving an
absolute path.

Environment
-----------

    Samba:             4.24.4
    Backend:           vfs_ceph_new
    Snapshot module:   ceph_snapshots
    Filesystem access: libcephfs
    Share path:        /test
    OS:                Linux
    Ceph/libcephfs:    Ceph 18.2.8

Relevant smb.conf:

    [test]
        path = /test
        read only = no
        vfs objects = ceph_snapshots ceph_new
        ceph_new:config_file = /etc/ceph/ceph.conf
        ceph_new:user_id = test
        ceph_new:filesystem = [filesystem name]

The problem is specific to vfs_ceph_new. shadow_copy2 working through a
kernel-mounted CephFS does not exercise this backend path.

Reproducer
----------

Create a directory and a CephFS snapshot, for example from a kernel or FUSE
mount:

    mkdir -p /test/test2
    mkdir /test/test2/.snap/test123

Obtain the @GMT label advertised for the snapshot and access it through
smbclient:

    smbclient //localhost/test -U test%test

    smb: \> allinfo @GMT-2026.08.18-13.09.26\test2\

The client disconnects with:

    NT_STATUS_CONNECTION_DISCONNECTED getting alt name for \
    \@GMT-2026.08.18-13.09.26\test2\

The smbd process receives SIGSEGV.

Observed log
------------

The relevant log sequence is:

    vfs_ceph_add_fh: [CEPH] add fh: fsp_name=/ ret=0
    vfs_ceph_ll_lookup: [CEPH] ceph_ll_lookup:
        parent-ino=1099511627805 name=/
    vfs_ceph_ll_lookup: [CEPH] ceph_ll_lookup:
        parent-ino=1099511627805 name=/ ret=0
    vfs_ceph_openat: [CEPH] openat: fsp_name=/ ...
    vfs_ceph_ll_lookup: [CEPH] ceph_ll_lookup:
        parent-ino=1099511627805 name=test
    INTERNAL ERROR: Signal 11: Segmentation fault in smbd

The important backtrace is:

    libcephfs.so: ceph_ll_lookup
    ceph_new.so: vfs_ceph_openat
    smbd: openat_pathref_fsp_nosymlink
    smbd: filename_convert_dirfsp_nosymlink
    smbd: fd_openat
    smbd: open_internal_dirfsp
    smbd: OpenDir
    ceph_snapshots.so: ceph_snap_gmt_convert_dir
    ceph_snapshots.so: ceph_snap_gmt_convert
    ceph_snapshots.so: ceph_snap_gmt_openat

Analysis
--------

ceph_snapshots converts the @GMT name to an absolute physical CephFS path
below the share connectpath, for example:

    /test/test2/.snap/test123

When Samba resolves an absolute pathname, fd_openat() first calls
openat_pathref_fsp_rootdir(). This constructs a synthetic root pathref by
performing an open equivalent to:

    SMB_VFS_OPENAT(conn->cwd_fsp, "/", ...)

As with POSIX openat(), the dirfsp must be ignored when the supplied name is
absolute.

vfs_ceph_new currently does the following instead:

1. vfs_ceph_igetd() obtains the inode associated with conn->cwd_fsp.
2. For this share, that inode represents the share root "/test", not the
    physical CephFS root.
3. vfs_ceph_openat() calls ceph_ll_lookup() with that inode and the name "/".
4. The resulting synthetic "/" pathref therefore remains associated with the
    share root.
5. Samba removes the leading slash from the absolute path and resolves its
    first component, "test", relative to that synthetic root.
6. vfs_ceph_new consequently calls:

        ceph_ll_lookup(parent=inode-for-/test, name="test")

    instead of looking up "test" below the physical CephFS root.
7. In the reproduced case, libcephfs segfaults in ceph_ll_lookup().

The initial lookup of "/" and the subsequent lookup of "test" can be seen
directly in the log above.

Expected result
---------------

The synthetic "/" pathref must represent the physical CephFS root.

The converted path should therefore resolve as:

    physical CephFS root
        -> test
        -> test2
        -> .snap
        -> test123

Normal relative opens below the share root must continue to use the existing
share-root inode.

Accessing the advertised @GMT path should succeed without an smbd crash or
client disconnect:

    allinfo @GMT-YYYY.MM.DD-HH.MM.SS\test2\
    ls      @GMT-YYYY.MM.DD-HH.MM.SS\test2\
    cd      @GMT-YYYY.MM.DD-HH.MM.SS\test2\

Proposed fix
------------

vfs_ceph_new already loads the libcephfs ceph_ll_lookup_root() API.

vfs_ceph_openat() should recognize the special absolute "/" open used to
construct Samba's root pathref and populate the new FSP with the inode returned
by ceph_ll_lookup_root(), rather than looking up "/" below dirfsp.

The root inode reference must be retained by the FSP and released with
ceph_ll_put() through the existing FSP cleanup path.

All non-root opens should retain the current inode-relative behavior.

A proposed patch implementing this narrowly scoped behavior is available and
can be attached to this bug.

Secondary symptoms
------------------

Before reproducing the segfault, the same configuration also produced errors
such as:

    FSCTL_GET_SHADOW_COPY_DATA: connectpath /test, failed -
    NT_STATUS_OBJECT_NAME_NOT_FOUND

and:

    NT_STATUS_OBJECT_NAME_NOT_FOUND getting shadow copy data for \
    \test2\.snap\test123\rpc.py

Empty snapshot enumeration also exposed a talloc-frame cleanup warning and a
too-small empty FSCTL response. Those are separate defensive issues.

The SIGSEGV described here is the primary bug: it demonstrates that
vfs_ceph_new is receiving Samba's synthetic absolute-root pathref but mapping
it to the share-root inode.

Related bugs
------------

Bug 15818:
    vfs_ceph_new module does not work with other modules for snapshot
    management.

Bug 16176:
    vfs_ceph_snapshots constructs non-canonical paths containing repeated
    slashes.

The bug reported here remains reproducible with the bug 16176 fix present.
It concerns the vfs_ceph_new absolute-path/pathref contract rather than slash
canonicalization in vfs_ceph_snapshots.