Page MenuHomeFreeBSD

D27011.diff
No OneTemporary

D27011.diff

Index: head/share/man/man4/unix.4
===================================================================
--- head/share/man/man4/unix.4
+++ head/share/man/man4/unix.4
@@ -28,7 +28,7 @@
.\" @(#)unix.4 8.1 (Berkeley) 6/9/93
.\" $FreeBSD$
.\"
-.Dd August 3, 2020
+.Dd November 2, 2020
.Dt UNIX 4
.Os
.Sh NAME
@@ -201,7 +201,7 @@
.Xr setsockopt 2
and tested with
.Xr getsockopt 2 :
-.Bl -tag -width ".Dv LOCAL_CONNWAIT"
+.Bl -tag -width ".Dv LOCAL_CREDS_PERSISTENT"
.It Dv LOCAL_CREDS
This option may be enabled on
.Dv SOCK_DGRAM ,
@@ -287,6 +287,19 @@
Therefore, a message accompanied by a particular
.Fa sc_euid
value should not be trusted as being from that user.
+.It Dv LOCAL_CREDS_PERSISTENT
+This option is similar to
+.Dv LOCAL_CREDS ,
+except that socket credentials are passed on every read from a
+.Dv SOCK_STREAM
+or
+.Dv SOCK_SEQPACKET
+socket, instead of just the first read.
+The
+.Dv LOCAL_CREDS
+and
+.Dv LOCAL_CREDS_PERSISTENT
+options are mutually exclusive.
.It Dv LOCAL_CONNWAIT
Used with
.Dv SOCK_STREAM
Index: head/sys/kern/uipc_usrreq.c
===================================================================
--- head/sys/kern/uipc_usrreq.c
+++ head/sys/kern/uipc_usrreq.c
@@ -1040,7 +1040,7 @@
break;
}
- if (unp2->unp_flags & UNP_WANTCRED)
+ if (unp2->unp_flags & UNP_WANTCRED_MASK)
control = unp_addsockcred(td, control);
if (unp->unp_addr != NULL)
from = (struct sockaddr *)unp->unp_addr;
@@ -1094,12 +1094,13 @@
break;
}
SOCKBUF_LOCK(&so2->so_rcv);
- if (unp2->unp_flags & UNP_WANTCRED) {
+ if (unp2->unp_flags & UNP_WANTCRED_MASK) {
/*
- * Credentials are passed only once on SOCK_STREAM
- * and SOCK_SEQPACKET.
+ * Credentials are passed only once on SOCK_STREAM and
+ * SOCK_SEQPACKET (LOCAL_CREDS => WANTCRED_ONESHOT), or
+ * forever (LOCAL_CREDS_PERSISTENT => WANTCRED_ALWAYS).
*/
- unp2->unp_flags &= ~UNP_WANTCRED;
+ unp2->unp_flags &= ~UNP_WANTCRED_ONESHOT;
control = unp_addsockcred(td, control);
}
@@ -1405,10 +1406,16 @@
case LOCAL_CREDS:
/* Unlocked read. */
- optval = unp->unp_flags & UNP_WANTCRED ? 1 : 0;
+ optval = unp->unp_flags & UNP_WANTCRED_ONESHOT ? 1 : 0;
error = sooptcopyout(sopt, &optval, sizeof(optval));
break;
+ case LOCAL_CREDS_PERSISTENT:
+ /* Unlocked read. */
+ optval = unp->unp_flags & UNP_WANTCRED_ALWAYS ? 1 : 0;
+ error = sooptcopyout(sopt, &optval, sizeof(optval));
+ break;
+
case LOCAL_CONNWAIT:
/* Unlocked read. */
optval = unp->unp_flags & UNP_CONNWAIT ? 1 : 0;
@@ -1424,28 +1431,38 @@
case SOPT_SET:
switch (sopt->sopt_name) {
case LOCAL_CREDS:
+ case LOCAL_CREDS_PERSISTENT:
case LOCAL_CONNWAIT:
error = sooptcopyin(sopt, &optval, sizeof(optval),
sizeof(optval));
if (error)
break;
-#define OPTSET(bit) do { \
+#define OPTSET(bit, exclusive) do { \
UNP_PCB_LOCK(unp); \
- if (optval) \
- unp->unp_flags |= bit; \
- else \
- unp->unp_flags &= ~bit; \
+ if (optval) { \
+ if ((unp->unp_flags & (exclusive)) != 0) { \
+ UNP_PCB_UNLOCK(unp); \
+ error = EINVAL; \
+ break; \
+ } \
+ unp->unp_flags |= (bit); \
+ } else \
+ unp->unp_flags &= ~(bit); \
UNP_PCB_UNLOCK(unp); \
} while (0)
switch (sopt->sopt_name) {
case LOCAL_CREDS:
- OPTSET(UNP_WANTCRED);
+ OPTSET(UNP_WANTCRED_ONESHOT, UNP_WANTCRED_ALWAYS);
break;
+ case LOCAL_CREDS_PERSISTENT:
+ OPTSET(UNP_WANTCRED_ALWAYS, UNP_WANTCRED_ONESHOT);
+ break;
+
case LOCAL_CONNWAIT:
- OPTSET(UNP_CONNWAIT);
+ OPTSET(UNP_CONNWAIT, 0);
break;
default:
@@ -1651,8 +1668,7 @@
memcpy(&server_unp->unp_peercred, &listen_unp->unp_peercred,
sizeof(server_unp->unp_peercred));
server_unp->unp_flags |= UNP_HAVEPC;
- if (listen_unp->unp_flags & UNP_WANTCRED)
- client_unp->unp_flags |= UNP_WANTCRED;
+ client_unp->unp_flags |= (listen_unp->unp_flags & UNP_WANTCRED_MASK);
}
static int
@@ -2853,8 +2869,12 @@
db_printf("%sUNP_HAVEPC", comma ? ", " : "");
comma = 1;
}
- if (unp_flags & UNP_WANTCRED) {
- db_printf("%sUNP_WANTCRED", comma ? ", " : "");
+ if (unp_flags & UNP_WANTCRED_ALWAYS) {
+ db_printf("%sUNP_WANTCRED_ALWAYS", comma ? ", " : "");
+ comma = 1;
+ }
+ if (unp_flags & UNP_WANTCRED_ONESHOT) {
+ db_printf("%sUNP_WANTCRED_ONESHOT", comma ? ", " : "");
comma = 1;
}
if (unp_flags & UNP_CONNWAIT) {
Index: head/sys/sys/un.h
===================================================================
--- head/sys/sys/un.h
+++ head/sys/sys/un.h
@@ -67,6 +67,7 @@
/* Socket options. */
#define LOCAL_PEERCRED 1 /* retrieve peer credentials */
#define LOCAL_CREDS 2 /* pass credentials to receiver */
+#define LOCAL_CREDS_PERSISTENT 3 /* pass credentials to receiver */
#define LOCAL_CONNWAIT 4 /* connects block until accepted */
/* Start of reserved space for third-party socket options. */
Index: head/sys/sys/unpcb.h
===================================================================
--- head/sys/sys/unpcb.h
+++ head/sys/sys/unpcb.h
@@ -107,9 +107,12 @@
* to determine whether the contents should be sent to the user or
* not.
*/
-#define UNP_HAVEPC 0x001
-#define UNP_WANTCRED 0x004 /* credentials wanted */
+#define UNP_HAVEPC 0x001
+#define UNP_WANTCRED_ALWAYS 0x002 /* credentials wanted always */
+#define UNP_WANTCRED_ONESHOT 0x004 /* credentials wanted once */
#define UNP_CONNWAIT 0x008 /* connect blocks until accepted */
+
+#define UNP_WANTCRED_MASK (UNP_WANTCRED_ONESHOT | UNP_WANTCRED_ALWAYS)
/*
* These flags are used to handle non-atomicity in connect() and bind()

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 27, 7:18 AM (10 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17814808
Default Alt Text
D27011.diff (5 KB)

Event Timeline