svn commit: r367776 - in head: share/man/man4 sys/compat/linux sys/kern sys/sys
Conrad Meyer
cem at FreeBSD.org
Tue Nov 17 20:01:22 UTC 2020
Author: cem
Date: Tue Nov 17 20:01:21 2020
New Revision: 367776
URL: https://svnweb.freebsd.org/changeset/base/367776
Log:
unix(4): Enhance LOCAL_CREDS_PERSISTENT ABI
As this ABI is still fresh (r367287), let's correct some mistakes now:
- Version the structure to allow for future changes
- Include sender's pid in control message structure
- Use a distinct control message type from the cmsgcred / sockcred mess
Discussed with: kib, markj, trasz
Differential Revision: https://reviews.freebsd.org/D27084
Modified:
head/share/man/man4/unix.4
head/sys/compat/linux/linux_socket.c
head/sys/kern/uipc_usrreq.c
head/sys/sys/socket.h
Modified: head/share/man/man4/unix.4
==============================================================================
--- head/share/man/man4/unix.4 Tue Nov 17 19:56:47 2020 (r367775)
+++ head/share/man/man4/unix.4 Tue Nov 17 20:01:21 2020 (r367776)
@@ -28,7 +28,7 @@
.\" @(#)unix.4 8.1 (Berkeley) 6/9/93
.\" $FreeBSD$
.\"
-.Dd November 2, 2020
+.Dd November 9, 2020
.Dt UNIX 4
.Os
.Sh NAME
@@ -295,6 +295,41 @@ except that socket credentials are passed on every rea
or
.Dv SOCK_SEQPACKET
socket, instead of just the first read.
+Additionally, the
+.Va msg_control
+field in the
+.Vt msghdr
+structure points to a buffer that contains a
+.Vt cmsghdr
+structure followed by a variable length
+.Vt sockcred2
+structure, defined in
+.In sys/socket.h
+as follows:
+.Bd -literal
+struct sockcred2 {
+ int sc_version; /* version of this structure */
+ pid_t sc_pid; /* PID of sending process */
+ uid_t sc_uid; /* real user id */
+ uid_t sc_euid; /* effective user id */
+ gid_t sc_gid; /* real group id */
+ gid_t sc_egid; /* effective group id */
+ int sc_ngroups; /* number of supplemental groups */
+ gid_t sc_groups[1]; /* variable length */
+};
+.Ed
+.Pp
+The current version is zero.
+.Pp
+The
+.Vt cmsghdr
+fields have the following values:
+.Bd -literal
+cmsg_len = CMSG_LEN(SOCKCRED2SIZE(ngroups))
+cmsg_level = SOL_SOCKET
+cmsg_type = SCM_CREDS2
+.Ed
+.Pp
The
.Dv LOCAL_CREDS
and
Modified: head/sys/compat/linux/linux_socket.c
==============================================================================
--- head/sys/compat/linux/linux_socket.c Tue Nov 17 19:56:47 2020 (r367775)
+++ head/sys/compat/linux/linux_socket.c Tue Nov 17 20:01:21 2020 (r367776)
@@ -644,6 +644,8 @@ bsd_to_linux_cmsg_type(int cmsg_type)
return (LINUX_SCM_RIGHTS);
case SCM_CREDS:
return (LINUX_SCM_CREDENTIALS);
+ case SCM_CREDS2:
+ return (LINUX_SCM_CREDENTIALS);
case SCM_TIMESTAMP:
return (LINUX_SCM_TIMESTAMP);
}
@@ -1508,6 +1510,7 @@ linux_recvmsg_common(struct thread *td, l_int s, struc
{
struct cmsghdr *cm;
struct cmsgcred *cmcred;
+ struct sockcred2 *scred;
struct l_cmsghdr *linux_cmsg = NULL;
struct l_ucred linux_ucred;
socklen_t datalen, maxlen, outlen;
@@ -1627,6 +1630,16 @@ linux_recvmsg_common(struct thread *td, l_int s, struc
linux_ucred.pid = cmcred->cmcred_pid;
linux_ucred.uid = cmcred->cmcred_uid;
linux_ucred.gid = cmcred->cmcred_gid;
+ data = &linux_ucred;
+ datalen = sizeof(linux_ucred);
+ break;
+
+ case SCM_CREDS2:
+ scred = data;
+ bzero(&linux_ucred, sizeof(linux_ucred));
+ linux_ucred.pid = scred->sc_pid;
+ linux_ucred.uid = scred->sc_uid;
+ linux_ucred.gid = scred->sc_gid;
data = &linux_ucred;
datalen = sizeof(linux_ucred);
break;
Modified: head/sys/kern/uipc_usrreq.c
==============================================================================
--- head/sys/kern/uipc_usrreq.c Tue Nov 17 19:56:47 2020 (r367775)
+++ head/sys/kern/uipc_usrreq.c Tue Nov 17 20:01:21 2020 (r367776)
@@ -308,7 +308,7 @@ static int unp_internalize(struct mbuf **, struct thre
static void unp_internalize_fp(struct file *);
static int unp_externalize(struct mbuf *, struct mbuf **, int);
static int unp_externalize_fp(struct file *);
-static struct mbuf *unp_addsockcred(struct thread *, struct mbuf *);
+static struct mbuf *unp_addsockcred(struct thread *, struct mbuf *, int);
static void unp_process_defers(void * __unused, int);
static void
@@ -1043,7 +1043,8 @@ uipc_send(struct socket *so, int flags, struct mbuf *m
}
if (unp2->unp_flags & UNP_WANTCRED_MASK)
- control = unp_addsockcred(td, control);
+ control = unp_addsockcred(td, control,
+ unp2->unp_flags);
if (unp->unp_addr != NULL)
from = (struct sockaddr *)unp->unp_addr;
else
@@ -1102,8 +1103,8 @@ uipc_send(struct socket *so, int flags, struct mbuf *m
* SOCK_SEQPACKET (LOCAL_CREDS => WANTCRED_ONESHOT), or
* forever (LOCAL_CREDS_PERSISTENT => WANTCRED_ALWAYS).
*/
+ control = unp_addsockcred(td, control, unp2->unp_flags);
unp2->unp_flags &= ~UNP_WANTCRED_ONESHOT;
- control = unp_addsockcred(td, control);
}
/*
@@ -2383,34 +2384,58 @@ out:
}
static struct mbuf *
-unp_addsockcred(struct thread *td, struct mbuf *control)
+unp_addsockcred(struct thread *td, struct mbuf *control, int mode)
{
struct mbuf *m, *n, *n_prev;
- struct sockcred *sc;
const struct cmsghdr *cm;
- int ngroups;
- int i;
+ int ngroups, i, cmsgtype;
+ size_t ctrlsz;
ngroups = MIN(td->td_ucred->cr_ngroups, CMGROUP_MAX);
- m = sbcreatecontrol(NULL, SOCKCREDSIZE(ngroups), SCM_CREDS, SOL_SOCKET);
+ if (mode & UNP_WANTCRED_ALWAYS) {
+ ctrlsz = SOCKCRED2SIZE(ngroups);
+ cmsgtype = SCM_CREDS2;
+ } else {
+ ctrlsz = SOCKCREDSIZE(ngroups);
+ cmsgtype = SCM_CREDS;
+ }
+
+ m = sbcreatecontrol(NULL, ctrlsz, cmsgtype, SOL_SOCKET);
if (m == NULL)
return (control);
- sc = (struct sockcred *) CMSG_DATA(mtod(m, struct cmsghdr *));
- sc->sc_uid = td->td_ucred->cr_ruid;
- sc->sc_euid = td->td_ucred->cr_uid;
- sc->sc_gid = td->td_ucred->cr_rgid;
- sc->sc_egid = td->td_ucred->cr_gid;
- sc->sc_ngroups = ngroups;
- for (i = 0; i < sc->sc_ngroups; i++)
- sc->sc_groups[i] = td->td_ucred->cr_groups[i];
+ if (mode & UNP_WANTCRED_ALWAYS) {
+ struct sockcred2 *sc;
+ sc = (void *)CMSG_DATA(mtod(m, struct cmsghdr *));
+ sc->sc_version = 0;
+ sc->sc_pid = td->td_proc->p_pid;
+ sc->sc_uid = td->td_ucred->cr_ruid;
+ sc->sc_euid = td->td_ucred->cr_uid;
+ sc->sc_gid = td->td_ucred->cr_rgid;
+ sc->sc_egid = td->td_ucred->cr_gid;
+ sc->sc_ngroups = ngroups;
+ for (i = 0; i < sc->sc_ngroups; i++)
+ sc->sc_groups[i] = td->td_ucred->cr_groups[i];
+ } else {
+ struct sockcred *sc;
+
+ sc = (void *)CMSG_DATA(mtod(m, struct cmsghdr *));
+ sc->sc_uid = td->td_ucred->cr_ruid;
+ sc->sc_euid = td->td_ucred->cr_uid;
+ sc->sc_gid = td->td_ucred->cr_rgid;
+ sc->sc_egid = td->td_ucred->cr_gid;
+ sc->sc_ngroups = ngroups;
+ for (i = 0; i < sc->sc_ngroups; i++)
+ sc->sc_groups[i] = td->td_ucred->cr_groups[i];
+ }
+
/*
* Unlink SCM_CREDS control messages (struct cmsgcred), since just
* created SCM_CREDS control message (struct sockcred) has another
* format.
*/
- if (control != NULL)
+ if (control != NULL && cmsgtype == SCM_CREDS)
for (n = control, n_prev = NULL; n != NULL;) {
cm = mtod(n, struct cmsghdr *);
if (cm->cmsg_level == SOL_SOCKET &&
Modified: head/sys/sys/socket.h
==============================================================================
--- head/sys/sys/socket.h Tue Nov 17 19:56:47 2020 (r367775)
+++ head/sys/sys/socket.h Tue Nov 17 20:01:21 2020 (r367776)
@@ -510,7 +510,7 @@ struct cmsgcred {
};
/*
- * Socket credentials.
+ * Socket credentials (LOCAL_CREDS).
*/
struct sockcred {
uid_t sc_uid; /* real user id */
@@ -527,6 +527,22 @@ struct sockcred {
#define SOCKCREDSIZE(ngrps) \
(sizeof(struct sockcred) + (sizeof(gid_t) * ((ngrps) - 1)))
+/*
+ * Socket credentials (LOCAL_CREDS_PERSISTENT).
+ */
+struct sockcred2 {
+ int sc_version; /* version of this structure */
+ pid_t sc_pid; /* PID of sending process */
+ uid_t sc_uid; /* real user id */
+ uid_t sc_euid; /* effective user id */
+ gid_t sc_gid; /* real group id */
+ gid_t sc_egid; /* effective group id */
+ int sc_ngroups; /* number of supplemental groups */
+ gid_t sc_groups[1]; /* variable length */
+};
+#define SOCKCRED2SIZE(ngrps) \
+ (sizeof(struct sockcred2) + (sizeof(gid_t) * ((ngrps) - 1)))
+
#endif /* __BSD_VISIBLE */
/* given pointer to struct cmsghdr, return pointer to data */
@@ -571,6 +587,7 @@ struct sockcred {
#define SCM_REALTIME 0x05 /* timestamp (struct timespec) */
#define SCM_MONOTONIC 0x06 /* timestamp (struct timespec) */
#define SCM_TIME_INFO 0x07 /* timestamp info */
+#define SCM_CREDS2 0x08 /* process creds (struct sockcred2) */
struct sock_timestamp_info {
__uint32_t st_info_flags;
More information about the svn-src-head
mailing list