Page MenuHomeFreeBSD

D48649.diff
No OneTemporary

D48649.diff

diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -3249,8 +3249,7 @@
; 576 is initialised by the krpc code, if present.
576 AUE_NULL NOSTD {
int rpctls_syscall(
- int op,
- _In_z_ const char *path
+ uint64_t socookie
);
}
577 AUE_SPECIALFD STD|CAPENABLED {
diff --git a/sys/rpc/rpcsec_tls.h b/sys/rpc/rpcsec_tls.h
--- a/sys/rpc/rpcsec_tls.h
+++ b/sys/rpc/rpcsec_tls.h
@@ -28,12 +28,8 @@
#ifndef _RPC_RPCSEC_TLS_H_
#define _RPC_RPCSEC_TLS_H_
-/* Operation values for rpctls syscall. */
-#define RPCTLS_SYSC_CLSOCKET 2
-#define RPCTLS_SYSC_SRVSOCKET 5
-
-/* System call used by the rpctlscd, rpctlssd daemons. */
-int rpctls_syscall(int, const char *);
+/* System call used by the rpc.tlsclntd(8), rpc.tlsservd(8) daemons. */
+int rpctls_syscall(uint64_t);
/* Flag bits to indicate certificate results. */
#define RPCTLS_FLAGS_HANDSHAKE 0x01
diff --git a/sys/rpc/rpcsec_tls/rpctls_impl.c b/sys/rpc/rpcsec_tls/rpctls_impl.c
--- a/sys/rpc/rpcsec_tls/rpctls_impl.c
+++ b/sys/rpc/rpcsec_tls/rpctls_impl.c
@@ -88,6 +88,7 @@
CLIENT *cl;
SVCXPRT *xp;
};
+ bool server;
};
static RB_HEAD(upsock_t, upsock) upcall_sockets;
@@ -169,7 +170,7 @@
sys_rpctls_syscall(struct thread *td, struct rpctls_syscall_args *uap)
{
struct file *fp;
- struct upsock *ups;
+ struct upsock *upsp, ups;
int fd = -1, error;
error = priv_check(td, PRIV_NFS_DAEMON);
@@ -177,52 +178,51 @@
return (error);
KRPC_CURVNET_SET(KRPC_TD_TO_VNET(td));
- switch (uap->op) {
- case RPCTLS_SYSC_CLSOCKET:
- case RPCTLS_SYSC_SRVSOCKET:
- mtx_lock(&rpctls_lock);
- ups = RB_FIND(upsock_t, &upcall_sockets,
- &(struct upsock){
- .so = __DECONST(struct socket *, uap->path) });
- if (__predict_true(ups != NULL))
- RB_REMOVE(upsock_t, &upcall_sockets, ups);
- mtx_unlock(&rpctls_lock);
- if (ups == NULL) {
- printf("%s: socket lookup failed\n", __func__);
- error = EPERM;
- break;
- }
- if ((error = falloc(td, &fp, &fd, 0)) != 0)
- break;
- soref(ups->so);
- switch (uap->op) {
- case RPCTLS_SYSC_CLSOCKET:
- /*
- * Initialize TLS state so that clnt_vc_destroy() will
- * not close the socket and will leave that for the
- * daemon to do.
- */
- CLNT_CONTROL(ups->cl, CLSET_TLS,
- &(int){RPCTLS_INHANDSHAKE});
- break;
- case RPCTLS_SYSC_SRVSOCKET:
- /*
- * Once this file descriptor is associated
- * with the socket, it cannot be closed by
- * the server side krpc code (svc_vc.c).
- */
- sx_xlock(&ups->xp->xp_lock);
- ups->xp->xp_tls = RPCTLS_FLAGS_HANDSHFAIL;
- sx_xunlock(&ups->xp->xp_lock);
- break;
- }
- finit(fp, FREAD | FWRITE, DTYPE_SOCKET, ups->so, &socketops);
- fdrop(fp, td); /* Drop fp reference. */
- td->td_retval[0] = fd;
- break;
- default:
- error = EINVAL;
+ mtx_lock(&rpctls_lock);
+ upsp = RB_FIND(upsock_t, &upcall_sockets,
+ &(struct upsock){
+ .so = __DECONST(struct socket *, uap->socookie) });
+ if (__predict_true(upsp != NULL)) {
+ RB_REMOVE(upsock_t, &upcall_sockets, upsp);
+ /*
+ * The upsp points to stack of NFS mounting thread. Even
+ * though we removed it from the tree, we still don't own it.
+ * Make a copy before releasing the lock. The mounting thread
+ * may timeout the RPC and unroll its stack.
+ */
+ ups = *upsp;
+ }
+ mtx_unlock(&rpctls_lock);
+ if (upsp == NULL) {
+ KRPC_CURVNET_RESTORE();
+ printf("%s: socket lookup failed\n", __func__);
+ return (EPERM);
+ }
+ if ((error = falloc(td, &fp, &fd, 0)) != 0) {
+ KRPC_CURVNET_RESTORE();
+ return (error);
+ }
+ soref(ups.so);
+ if (ups.server) {
+ /*
+ * Once this file descriptor is associated
+ * with the socket, it cannot be closed by
+ * the server side krpc code (svc_vc.c).
+ */
+ sx_xlock(&ups.xp->xp_lock);
+ ups.xp->xp_tls = RPCTLS_FLAGS_HANDSHFAIL;
+ sx_xunlock(&ups.xp->xp_lock);
+ } else {
+ /*
+ * Initialize TLS state so that clnt_vc_destroy() will
+ * not close the socket and will leave that for the
+ * daemon to do.
+ */
+ CLNT_CONTROL(ups.cl, CLSET_TLS, &(int){RPCTLS_INHANDSHAKE});
}
+ finit(fp, FREAD | FWRITE, DTYPE_SOCKET, ups.so, &socketops);
+ fdrop(fp, td); /* Drop fp reference. */
+ td->td_retval[0] = fd;
KRPC_CURVNET_RESTORE();
return (error);
@@ -269,6 +269,7 @@
struct upsock ups = {
.so = so,
.cl = newclient,
+ .server = false,
};
CLIENT *cl = KRPC_VNET(rpctls_connect_handle);
@@ -390,6 +391,7 @@
struct upsock ups = {
.so = xprt->xp_socket,
.xp = xprt,
+ .server = true,
};
CLIENT *cl = KRPC_VNET(rpctls_server_handle);
struct rpctlssd_connect_arg arg;
diff --git a/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.c b/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.c
--- a/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.c
+++ b/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.c
@@ -258,7 +258,7 @@
rpctls_verbose_out("rpctlsd_connect: started\n");
/* Get the socket fd from the kernel. */
- s = rpctls_syscall(RPCTLS_SYSC_CLSOCKET, (char *)argp->socookie);
+ s = rpctls_syscall(argp->socookie);
if (s < 0) {
result->reterr = RPCTLSERR_NOSOCKET;
return (TRUE);
diff --git a/usr.sbin/rpc.tlsservd/rpc.tlsservd.c b/usr.sbin/rpc.tlsservd/rpc.tlsservd.c
--- a/usr.sbin/rpc.tlsservd/rpc.tlsservd.c
+++ b/usr.sbin/rpc.tlsservd/rpc.tlsservd.c
@@ -403,7 +403,7 @@
}
/* Get the socket fd from the kernel. */
- s = rpctls_syscall(RPCTLS_SYSC_SRVSOCKET, (char *)socookie);
+ s = rpctls_syscall(socookie);
if (s < 0) {
rpctls_verbose_out("rpctlssd_connect_svc: rpctls_syscall "
"accept failed\n");

File Metadata

Mime Type
text/plain
Expires
Tue, Feb 4, 5:56 PM (17 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16458352
Default Alt Text
D48649.diff (5 KB)

Event Timeline