Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 May 2023 21:06:08 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 271704] O_PATH and acl_get_fd_np doesn't work on FreeBSD 13(.2) and causes vfs_zfsacl in Samba to fail
Message-ID:  <bug-271704-227-P1jQshIEBA@https.bugs.freebsd.org/bugzilla/>
In-Reply-To: <bug-271704-227@https.bugs.freebsd.org/bugzilla/>
References:  <bug-271704-227@https.bugs.freebsd.org/bugzilla/>

next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D271704

--- 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_P=
ATH
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 =3D fchmod(fsp_get_io_fd(fsp), mode);
                END_PROFILE(syscall_fchmod);
                return result;
        }

        if (fsp->fsp_flags.have_proc_fds) {
                int fd =3D fsp_get_pathref_fd(fsp);
                const char *p =3D NULL;
                char buf[PATH_MAX];

                p =3D sys_proc_fd_path(fd, buf, sizeof(buf));
                if (p !=3D NULL) {
                        result =3D chmod(p, mode);
                } else {
                        result =3D -1;
                }
                END_PROFILE(syscall_fchmod);
                return result;
        }

        /*=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
         * This is no longer a handle based call.=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
         */
        result =3D 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 =3D facl(fsp_get_io_fd(fsp), ACE_SETACL, naces, acebuf);
        } else {
#if defined(HAVE_OPENAT) && defined(O_EMPTY_PATH)
                fd =3D fsp_get_pathref_fd(fsp);

                /* First try this for versions of FreeBSD that allows facl(=
) on
O_PATH fd's */
                rv =3D facl(fd, ACE_SETACL, naces, acebuf);
                if (rv < 0 && errno =3D=3D EBADF) {
                        /* Fall back to getting a real fd via openat() */
                        int saved_errno, real_fd;

                        real_fd =3D openat(fd, "", O_EMPTY_PATH);
                        if (real_fd < 0) {
                                errno =3D EBADF;
                                return false;
                        }

                        rv =3D facl(real_fd, ACE_SETACL, naces, acebuf);
                        saved_errno =3D errno;
                        close(real_fd);
                        errno =3D saved_errno;
                }
#else
                /* Last ditch fallback */
                rv =3D acl(fsp->fsp_name->base_name, ACE_SETACL, naces, ace=
buf);
#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).

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-271704-227-P1jQshIEBA>