smbd: Simplify sys_proc_fd_path()
authorVolker Lendecke <vl@samba.org>
Sun, 15 Oct 2023 09:39:32 +0000 (11:39 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 1 Nov 2023 18:55:32 +0000 (18:55 +0000)
We know the buffer size up-front, create a struct for that. Also, I
think if we ever hit another /proc pattern this is very likely on a
different OS that could be handled by an #ifdef.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/include/proto.h
source3/lib/system.c
source3/modules/vfs_btrfs.c
source3/modules/vfs_default.c
source3/modules/vfs_gpfs.c
source3/modules/vfs_posixacl.c
source3/smbd/open.c

index 8a6b944a0d6dac7025e44c75b566b951a7e29747..bbb089a5908c6dd6467ed8e575c9a8e45c791092 100644 (file)
@@ -208,8 +208,11 @@ char *sys_realpath(const char *path);
 int sys_get_number_of_cores(void);
 #endif
 
+struct sys_proc_fd_path_buf {
+       char buf[35]; /* "/proc/self/fd/" + strlen(2^64) + 0-terminator */
+};
 bool sys_have_proc_fds(void);
-const char *sys_proc_fd_path(int fd, char *buf, size_t bufsize);
+char *sys_proc_fd_path(int fd, struct sys_proc_fd_path_buf *buf);
 
 struct stat;
 void init_stat_ex_from_stat (struct stat_ex *dst,
index 7c9a6b5fa083ce68c506e5e74c1effdf416faaac..132e5827b37fcb7a672f3673e999855f92d1bc06 100644 (file)
@@ -1016,22 +1016,10 @@ int sys_get_number_of_cores(void)
 }
 #endif
 
-static struct proc_fd_pattern {
-       const char *pattern;
-       const char *test_path;
-} proc_fd_patterns[] = {
-       /* Linux */
-       { "/proc/self/fd/%d", "/proc/self/fd/0" },
-       { NULL, NULL },
-};
-
-static const char *proc_fd_pattern;
-
 bool sys_have_proc_fds(void)
 {
-       static bool checked;
-       static bool have_proc_fds;
-       struct proc_fd_pattern *p = NULL;
+       static bool checked = false;
+       static bool have_proc_fds = false;
        struct stat sb;
        int ret;
 
@@ -1039,42 +1027,19 @@ bool sys_have_proc_fds(void)
                return have_proc_fds;
        }
 
-       for (p = &proc_fd_patterns[0]; p->test_path != NULL; p++) {
-               ret = stat(p->test_path, &sb);
-               if (ret != 0) {
-                       continue;
-               }
-               have_proc_fds = true;
-               proc_fd_pattern = p->pattern;
-               break;
-       }
-
+       ret = stat("/proc/self/fd/0", &sb);
+       have_proc_fds = (ret == 0);
        checked = true;
+
        return have_proc_fds;
 }
 
-const char *sys_proc_fd_path(int fd, char *buf, size_t bufsize)
+char *sys_proc_fd_path(int fd, struct sys_proc_fd_path_buf *buf)
 {
-       int written;
+       int written =
+               snprintf(buf->buf, sizeof(buf->buf), "/proc/self/fd/%d", fd);
 
-       if (!sys_have_proc_fds()) {
-               return NULL;
-       }
-
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-nonliteral"
-#endif
-       written = snprintf(buf,
-                          bufsize,
-                          proc_fd_pattern,
-                          fd);
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-       if (written >= bufsize) {
-               return NULL;
-       }
+       SMB_ASSERT(sys_have_proc_fds() && (written >= 0));
 
-       return buf;
+       return buf->buf;
 }
index 12517941ad0fb841921a6138c50e50ce8f3e0fb8..903125242876febad9c86042210ae5683402f336 100644 (file)
@@ -466,8 +466,7 @@ static NTSTATUS btrfs_fget_compression(struct vfs_handle_struct *handle,
                                       struct files_struct *fsp,
                                       uint16_t *_compression_fmt)
 {
-       char buf[PATH_MAX];
-       const char *p = NULL;
+       struct sys_proc_fd_path_buf buf;
        int ret;
        long flags = 0;
        int fsp_fd = fsp_get_pathref_fd(fsp);
@@ -493,14 +492,11 @@ static NTSTATUS btrfs_fget_compression(struct vfs_handle_struct *handle,
                return NT_STATUS_NOT_IMPLEMENTED;
        }
 
-       p = sys_proc_fd_path(fsp_fd, buf, sizeof(buf));
-       if (p == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       fd = open(p, O_RDONLY);
+       fd = open(sys_proc_fd_path(fsp_fd, &buf), O_RDONLY);
        if (fd == -1) {
-               DBG_DEBUG("/proc open of %s failed: %s\n", p, strerror(errno));
+               DBG_DEBUG("/proc open of %s failed: %s\n",
+                         buf.buf,
+                         strerror(errno));
                return map_nt_error_from_unix(errno);
        }
 
index 7fa6872d1716c8c35a4dbf97e8413174b62e41f8..052b0a4d21d9cdda1a58016b62319c76d53216c6 100644 (file)
@@ -2677,15 +2677,10 @@ static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t m
 
        if (fsp->fsp_flags.have_proc_fds) {
                int fd = fsp_get_pathref_fd(fsp);
-               const char *p = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
+
+               result = chmod(sys_proc_fd_path(fd, &buf), mode);
 
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p != NULL) {
-                       result = chmod(p, mode);
-               } else {
-                       result = -1;
-               }
                END_PROFILE(syscall_fchmod);
                return result;
        }
@@ -2713,15 +2708,10 @@ static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t ui
 
        if (fsp->fsp_flags.have_proc_fds) {
                int fd = fsp_get_pathref_fd(fsp);
-               const char *p = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
+
+               result = chown(sys_proc_fd_path(fd, &buf), uid, gid);
 
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p != NULL) {
-                       result = chown(p, uid, gid);
-               } else {
-                       result = -1;
-               }
                END_PROFILE(syscall_fchown);
                return result;
        }
@@ -2846,19 +2836,12 @@ static int vfswrap_fntimes(vfs_handle_struct *handle,
 
        if (fsp->fsp_flags.have_proc_fds) {
                int fd = fsp_get_pathref_fd(fsp);
-               const char *p = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
 
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p != NULL) {
-                       /*
-                        * The dirfd argument of utimensat is ignored when
-                        * pathname is an absolute path
-                        */
-                       result = utimensat(AT_FDCWD, p, times, 0);
-               } else {
-                       result = -1;
-               }
+               result = utimensat(AT_FDCWD,
+                                  sys_proc_fd_path(fd, &buf),
+                                  times,
+                                  0);
 
                goto out;
        }
@@ -3274,15 +3257,9 @@ static int vfswrap_fchflags(vfs_handle_struct *handle,
        }
 
        if (fsp->fsp_flags.have_proc_fds) {
-               const char *p = NULL;
-               char buf[PATH_MAX];
-
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return -1;
-               }
+               struct sys_proc_fd_path_buf buf;
 
-               return chflags(p, flags);
+               return chflags(sys_proc_fd_path(fd, &buf), flags);
        }
 
        /*
@@ -3521,15 +3498,9 @@ static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle,
        }
 
        if (fsp->fsp_flags.have_proc_fds) {
-               const char *p = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
 
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return -1;
-               }
-
-               return getxattr(p, name, value, size);
+               return getxattr(sys_proc_fd_path(fd, &buf), name, value, size);
        }
 
        /*
@@ -3847,15 +3818,9 @@ static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files
        }
 
        if (fsp->fsp_flags.have_proc_fds) {
-               const char *p = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
 
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return -1;
-               }
-
-               return listxattr(p, list, size);
+               return listxattr(sys_proc_fd_path(fd, &buf), list, size);
        }
 
        /*
@@ -3875,15 +3840,9 @@ static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_s
        }
 
        if (fsp->fsp_flags.have_proc_fds) {
-               const char *p = NULL;
-               char buf[PATH_MAX];
-
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return -1;
-               }
+               struct sys_proc_fd_path_buf buf;
 
-               return removexattr(p, name);
+               return removexattr(sys_proc_fd_path(fd, &buf), name);
        }
 
        /*
@@ -3903,15 +3862,13 @@ static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_stru
        }
 
        if (fsp->fsp_flags.have_proc_fds) {
-               const char *p = NULL;
-               char buf[PATH_MAX];
-
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return -1;
-               }
+               struct sys_proc_fd_path_buf buf;
 
-               return setxattr(p, name, value, size, flags);
+               return setxattr(sys_proc_fd_path(fd, &buf),
+                               name,
+                               value,
+                               size,
+                               flags);
        }
 
        /*
index 21ede6cea5a340ec7835b46463c3c1a26946d685..1c11809fb1b2fb9b4f4c6668340694811b8b3edd 100644 (file)
@@ -1446,7 +1446,7 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
 {
        struct gpfs_config_data *config;
        int fd = fsp_get_pathref_fd(fsp);
-       char buf[PATH_MAX];
+       struct sys_proc_fd_path_buf buf;
        const char *p = NULL;
        struct gpfs_iattr64 iattr = { };
        unsigned int litemask = 0;
@@ -1463,10 +1463,7 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
 
        if (fsp->fsp_flags.is_pathref && !config->pathref_ok.gpfs_fstat_x) {
                if (fsp->fsp_flags.have_proc_fds) {
-                       p = sys_proc_fd_path(fd, buf, sizeof(buf));
-                       if (p == NULL) {
-                               return NT_STATUS_NO_MEMORY;
-                       }
+                       p = sys_proc_fd_path(fd, &buf);
                } else {
                        p = fsp->fsp_name->base_name;
                }
@@ -1560,20 +1557,17 @@ static NTSTATUS vfs_gpfs_fset_dos_attributes(struct vfs_handle_struct *handle,
 
        if (fsp->fsp_flags.have_proc_fds) {
                int fd = fsp_get_pathref_fd(fsp);
-               const char *p = NULL;
-               char buf[PATH_MAX];
-
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
+               struct sys_proc_fd_path_buf buf;
 
-               ret = gpfswrap_set_winattrs_path(p,
+               ret = gpfswrap_set_winattrs_path(sys_proc_fd_path(fd, &buf),
                                                 GPFS_WINATTR_SET_ATTRS,
                                                 &attrs);
                if (ret == -1) {
-                       DBG_WARNING("Setting winattrs failed for [%s][%s]: %s\n",
-                                   p, fsp_str_dbg(fsp), strerror(errno));
+                       DBG_WARNING("Setting winattrs failed for "
+                                   "[%s][%s]: %s\n",
+                                   buf.buf,
+                                   fsp_str_dbg(fsp),
+                                   strerror(errno));
                        return map_nt_error_from_unix(errno);
                }
                return NT_STATUS_OK;
@@ -1728,18 +1722,16 @@ static int smbd_gpfs_set_times(struct files_struct *fsp,
 
        if (fsp->fsp_flags.have_proc_fds) {
                int fd = fsp_get_pathref_fd(fsp);
-               const char *p = NULL;
-               char buf[PATH_MAX];
-
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return -1;
-               }
+               struct sys_proc_fd_path_buf buf;
 
-               rc = gpfswrap_set_times_path(buf, flags, gpfs_times);
+               rc = gpfswrap_set_times_path(sys_proc_fd_path(fd, &buf),
+                                            flags,
+                                            gpfs_times);
                if (rc != 0) {
                        DBG_WARNING("gpfs_set_times_path(%s,%s) failed: %s\n",
-                                   fsp_str_dbg(fsp), p, strerror(errno));
+                                   fsp_str_dbg(fsp),
+                                   buf.buf,
+                                   strerror(errno));
                }
                return rc;
        }
@@ -1816,17 +1808,12 @@ static int vfs_gpfs_fntimes(struct vfs_handle_struct *handle,
 
        if (fsp->fsp_flags.have_proc_fds) {
                int fd = fsp_get_pathref_fd(fsp);
-               const char *p = NULL;
-               char buf[PATH_MAX];
-
-               p = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (p == NULL) {
-                       return -1;
-               }
+               struct sys_proc_fd_path_buf buf;
 
-               ret = gpfswrap_set_winattrs_path(p,
-                                                GPFS_WINATTR_SET_CREATION_TIME,
-                                                &attrs);
+               ret = gpfswrap_set_winattrs_path(
+                       sys_proc_fd_path(fd, &buf),
+                       GPFS_WINATTR_SET_CREATION_TIME,
+                       &attrs);
                if (ret == -1 && errno != ENOSYS) {
                        DBG_WARNING("Set GPFS ntimes failed %d\n", ret);
                        return -1;
index 2c2b68931a0f7a4b3b14925d472dd0628e8ea744..feb819de98259dc176651e86cde45a5089e67c27 100644 (file)
@@ -58,15 +58,9 @@ SMB_ACL_T posixacl_sys_acl_get_fd(vfs_handle_struct *handle,
                acl = acl_get_fd(fsp_get_io_fd(fsp));
        } else if (fsp->fsp_flags.have_proc_fds) {
                int fd = fsp_get_pathref_fd(fsp);
-               const char *proc_fd_path = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
 
-               proc_fd_path = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (proc_fd_path == NULL) {
-                       return NULL;
-               }
-
-               acl = acl_get_file(proc_fd_path, acl_type);
+               acl = acl_get_file(sys_proc_fd_path(fd, &buf), acl_type);
        } else {
                /*
                 * This is no longer a handle based call.
@@ -112,15 +106,9 @@ int posixacl_sys_acl_set_fd(vfs_handle_struct *handle,
        if (!fsp->fsp_flags.is_pathref && type == SMB_ACL_TYPE_ACCESS) {
                res = acl_set_fd(fd, acl);
        } else if (fsp->fsp_flags.have_proc_fds) {
-               const char *proc_fd_path = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
 
-               proc_fd_path = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (proc_fd_path == NULL) {
-                       acl_free(acl);
-                       return -1;
-               }
-               res = acl_set_file(proc_fd_path, acl_type, acl);
+               res = acl_set_file(sys_proc_fd_path(fd, &buf), acl_type, acl);
        } else {
                /*
                 * This is no longer a handle based call.
@@ -139,14 +127,9 @@ int posixacl_sys_acl_delete_def_fd(vfs_handle_struct *handle,
 {
        if (fsp->fsp_flags.have_proc_fds) {
                int fd = fsp_get_pathref_fd(fsp);
-               const char *proc_fd_path = NULL;
-               char buf[PATH_MAX];
+               struct sys_proc_fd_path_buf buf;
 
-               proc_fd_path = sys_proc_fd_path(fd, buf, sizeof(buf));
-               if (proc_fd_path == NULL) {
-                       return -1;
-               }
-               return acl_delete_def_file(proc_fd_path);
+               return acl_delete_def_file(sys_proc_fd_path(fd, &buf));
        }
 
        /*
index 14434ba6832d3bee2b92f8103f0f2cf5f12d5463..fa01a5d230f1ffd1107708e219c6977739575e76 100644 (file)
@@ -1217,8 +1217,7 @@ static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
                                   const struct vfs_open_how *how)
 {
        struct smb_filename proc_fname;
-       const char *p = NULL;
-       char buf[PATH_MAX];
+       struct sys_proc_fd_path_buf buf;
        int old_fd;
        int new_fd;
        NTSTATUS status;
@@ -1241,13 +1240,8 @@ static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
                return NT_STATUS_INVALID_HANDLE;
        }
 
-       p = sys_proc_fd_path(old_fd, buf, sizeof(buf));
-       if (p == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       proc_fname = (struct smb_filename) {
-               .base_name = discard_const_p(char, p),
+       proc_fname = (struct smb_filename){
+               .base_name = sys_proc_fd_path(old_fd, &buf),
        };
 
        fsp->fsp_flags.is_pathref = false;