[Bug 271704] O_PATH and acl_get_fd_np doesn't work on FreeBSD 13(.2) and causes vfs_zfsacl in Samba to fail
Date: Tue, 30 May 2023 21:06:08 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=271704 --- Comment #9 from Peter Eriksson <pen@lysator.liu.se> --- Linux uses the getxattr/setxattr calls for NFS stuff. Well, the generic way Samba handles O_PATH stuff on Linux for syscalls that fails is apparently to use /proc/self/fd/%d (where %d is the fd for the O_PATH descriptor) and then call the path-based variants of the syscall using that path instead of using the fd if (!fsp->fsp_flags.is_pathref) { result = fchmod(fsp_get_io_fd(fsp), mode); END_PROFILE(syscall_fchmod); return result; } 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) { result = chmod(p, mode); } else { result = -1; } END_PROFILE(syscall_fchmod); return result; } /* * This is no longer a handle based call. */ result = chmod(fsp->fsp_name->base_name, mode); (The last line of code is the reason most calls still work for a default-compiled Samba on FreeBSD 13 - it falls back to using the (insecure) full path based functionality... But that code was missing in the vfs_zfsacl module). For FreeBSD I think using openat(fd, "", O_EMPTY_PATH) is a cleaner way to get an fd that you can use... Something like this: if (!fsp->fsp_flags.is_pathref) { rv = facl(fsp_get_io_fd(fsp), ACE_SETACL, naces, acebuf); } else { #if defined(HAVE_OPENAT) && defined(O_EMPTY_PATH) fd = fsp_get_pathref_fd(fsp); /* First try this for versions of FreeBSD that allows facl() on O_PATH fd's */ rv = facl(fd, ACE_SETACL, naces, acebuf); if (rv < 0 && errno == EBADF) { /* Fall back to getting a real fd via openat() */ int saved_errno, real_fd; real_fd = openat(fd, "", O_EMPTY_PATH); if (real_fd < 0) { errno = EBADF; return false; } rv = facl(real_fd, ACE_SETACL, naces, acebuf); saved_errno = errno; close(real_fd); errno = saved_errno; } #else /* Last ditch fallback */ rv = acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf); #endif } (facl is a helper function in libsunacl that calls the right acl_get_fd_np/acl_get_file functions that Samba uses for compatibility with Solaris). -- You are receiving this mail because: You are the assignee for the bug.