Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109335853
D48649.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D48649.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D48649: rpcsec_tls: cleanup the rpctls_syscall()
Attached
Detach File
Event Timeline
Log In to Comment