Page MenuHomeFreeBSD

D58317.diff
No OneTemporary

D58317.diff

diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -3505,11 +3505,13 @@
}
static bool
-restrict_rights(struct file *fp, struct thread *td)
+restrict_rights(struct filedescent *fde, struct thread *td)
{
struct prison *prison1, *prison2;
- prison1 = fp->f_cred->cr_prison;
+ if ((fde->fde_flags & UF_RESOLVE_BENEATH) != 0)
+ return (true);
+ prison1 = fde->fde_file->f_cred->cr_prison;
prison2 = td->td_ucred->cr_prison;
return (prison1 != prison2 && prison1->pr_root != prison2->pr_root &&
prison2 != &prison0);
@@ -3590,7 +3592,7 @@
fp = fdep[i]->fde_file;
_finstall(fdesc, fp, *fdp, fdflags |
- (restrict_rights(fp, td) ?
+ (restrict_rights(fdep[i], td) ?
O_RESOLVE_BENEATH : 0), &fdep[i]->fde_caps);
unp_externalize_fp(fp);
}
@@ -3829,6 +3831,7 @@
fdep[i]->fde_file = fde->fde_file;
filecaps_copy(&fde->fde_caps,
&fdep[i]->fde_caps, true);
+ fdep[i]->fde_flags = fde->fde_flags;
unp_internalize_fp(fdep[i]->fde_file);
}
FILEDESC_SUNLOCK(fdesc);
diff --git a/tests/sys/kern/unix_passfd_test.c b/tests/sys/kern/unix_passfd_test.c
--- a/tests/sys/kern/unix_passfd_test.c
+++ b/tests/sys/kern/unix_passfd_test.c
@@ -1344,6 +1344,36 @@
err(1, "jail_remove");
}
+/*
+ * Verify that FD_RESOLVE_BENEATH is preserved when an fd is passed over a UNIX
+ * domain socket.
+ */
+ATF_TC_WITHOUT_HEAD(resolve_beneath_preserved);
+ATF_TC_BODY(resolve_beneath_preserved, tc)
+{
+ int fd[2], getfd, putfd, fdflags;
+
+ domainsocketpair(fd);
+ tempfile(&putfd);
+
+ fdflags = fcntl(putfd, F_GETFD);
+ ATF_REQUIRE(fdflags != -1);
+ ATF_REQUIRE(fcntl(putfd, F_SETFD, fdflags | FD_RESOLVE_BENEATH) != -1);
+ ATF_REQUIRE((fcntl(putfd, F_GETFD) & FD_RESOLVE_BENEATH) != 0);
+
+ sendfd(fd[0], putfd);
+ recvfd(fd[1], &getfd, 0);
+
+ fdflags = fcntl(getfd, F_GETFD);
+ ATF_REQUIRE(fdflags != -1);
+ ATF_REQUIRE_MSG((fdflags & FD_RESOLVE_BENEATH) != 0,
+ "FD_RESOLVE_BENEATH was not preserved across SCM_RIGHTS transfer");
+
+ ATF_REQUIRE(close(putfd) == 0);
+ ATF_REQUIRE(close(getfd) == 0);
+ closesocketpair(fd);
+}
+
ATF_TC_WITHOUT_HEAD(listening_socket);
ATF_TC_BODY(listening_socket, tc)
{
@@ -1397,6 +1427,7 @@
ATF_TP_ADD_TC(tp, empty_rights_message);
ATF_TP_ADD_TC(tp, control_creates_records);
ATF_TP_ADD_TC(tp, cross_jail_dirfd);
+ ATF_TP_ADD_TC(tp, resolve_beneath_preserved);
ATF_TP_ADD_TC(tp, listening_socket);
return (atf_no_error());

File Metadata

Mime Type
text/plain
Expires
Wed, Jul 22, 9:42 PM (19 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35295966
Default Alt Text
D58317.diff (2 KB)

Event Timeline