The branch, master has been updated
       via  ac7a16f9cc4 smbd: Fix crossing automounter mount points
      from  2d743185e0c vfs_ceph: use consistent code style when setting errno

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit ac7a16f9cc4bd97ef546d1b7b02605991000d0f9
Author: Volker Lendecke <v...@samba.org>
Date:   Fri Dec 29 16:54:56 2023 +0100

    smbd: Fix crossing automounter mount points
    
    We get ENOENT on /proc/self/fd/<fdnum> when we try to turn the
    mountpoint's O_PATH handle into a real one. This does not trigger a
    mount attempt, you have to use name-based calls.
    
    This is not the real fix, because if the autofs mount triggers, the
    inode number will change. For directories this is not a huge problem
    as we don't touch the share mode database before we open the "real"
    fd. We would only violate potential share modes with other pure
    READ_ATTRIBUTES (i.e. stat-) opens that came before the mount
    trigger.
    
    As I don't think share modes on directories are really relevant, I
    think we can live with this "fix". Once we do directory leases this
    will potentially change.
    
    As a quick remedy we could use our defer_open() mechanism that starts
    path processing from scratch. But as long as this seems not really
    required, we should not add users of this really bad way of going back
    to square 1.
    
    The "real" fix would be to go back to the point where we open the last
    component with openat(). In the retry round we need to do this without
    O_PATH to trigger the mount and only then do the initial fstat.
    
    Right now I don't see an easy way to properly test this
    behaviour. Intercepting with vfs_error_inject is certainly possible,
    but nailing the exact call would clutter the main code path. So I have
    just tested this manually.
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>
    
    Autobuild-User(master): Ralph Böhme <s...@samba.org>
    Autobuild-Date(master): Thu Jun 27 11:59:05 UTC 2024 on atb-devel-224

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/open.c | 26 ++++++++++++++++++++++++++
 source3/wscript     |  5 +++++
 2 files changed, 31 insertions(+)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 7d2227f9d9f..20db4cf5e23 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -43,6 +43,10 @@
 #include "lib/util/time_basic.h"
 #include "source3/smbd/dir.h"
 
+#if defined(HAVE_LINUX_MAGIC_H)
+#include <linux/magic.h>
+#endif
+
 extern const struct generic_mapping file_generic_mapping;
 
 struct deferred_open_record {
@@ -1180,6 +1184,27 @@ static NTSTATUS reopen_from_fsp(struct files_struct 
*dirfsp,
                                        fsp,
                                        how);
                if (new_fd == -1) {
+#if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
+                       if (S_ISDIR(fsp->fsp_name->st.st_ex_mode) &&
+                           (errno == ENOENT)) {
+                               struct statfs sbuf = {};
+                               int ret = fstatfs(old_fd, &sbuf);
+                               if (ret == -1) {
+                                       int saved_errno = errno;
+                                       DBG_ERR("fstatfs failed: %s\n",
+                                               strerror(errno));
+                                       errno = saved_errno;
+                               } else if (sbuf.f_type == AUTOFS_SUPER_MAGIC) {
+                                       /*
+                                        * When reopening an as-yet
+                                        * unmounted autofs mount
+                                        * point we get ENOENT. We
+                                        * have to retry pathbased.
+                                        */
+                                       goto namebased_open;
+                               }
+                       }
+#endif
                        status = map_nt_error_from_unix(errno);
                        fd_close(fsp);
                        return status;
@@ -1194,6 +1219,7 @@ static NTSTATUS reopen_from_fsp(struct files_struct 
*dirfsp,
                return NT_STATUS_OK;
        }
 
+namebased_open:
        /*
         * Close the existing pathref fd and set the fsp flag
         * is_pathref to false so we get a "normal" fd this time.
diff --git a/source3/wscript b/source3/wscript
index 4048ec5aad5..d8f04646b03 100644
--- a/source3/wscript
+++ b/source3/wscript
@@ -118,6 +118,7 @@ def configure(conf):
 
     conf.CHECK_HEADERS('netdb.h')
     conf.CHECK_HEADERS('linux/falloc.h linux/ioctl.h')
+    conf.CHECK_HEADERS('linux/magic.h')
 
     conf.CHECK_FUNCS('getcwd fchown chmod fchmod mknod mknodat')
     conf.CHECK_FUNCS('strtol strchr strupr chflags fchflags')
@@ -531,6 +532,10 @@ return acl_get_perm_np(permset_d, perm);
     if conf.CHECK_FUNCS('dirfd'):
         conf.DEFINE('HAVE_DIRFD_DECL', 1)
 
+    conf.CHECK_CODE('struct statfs fsd; int r = fstatfs(AT_FDCWD, &fsd);',
+                    'HAVE_FSTATFS',
+                    msg='Checking for fstatfs',
+                    headers='sys/statfs.h fcntl.h')
     conf.CHECK_CODE('struct statfs fsd; fsid_t fsid = fsd.f_fsid; return 
statfs(".", &fsd);',
                     'HAVE_STATFS_F_FSID',
                     msg="vfs_fileid checking for statfs() and struct 
statfs.f_fsid",


-- 
Samba Shared Repository

Reply via email to