[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.