From owner-svn-src-head@freebsd.org Tue Nov 3 01:17:46 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id C7140460CEA; Tue, 3 Nov 2020 01:17:46 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CQBjQ4yZcz4JkS; Tue, 3 Nov 2020 01:17:46 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 8A2BB123ED; Tue, 3 Nov 2020 01:17:46 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0A31HkhW042279; Tue, 3 Nov 2020 01:17:46 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0A31HjjR042275; Tue, 3 Nov 2020 01:17:45 GMT (envelope-from cem@FreeBSD.org) Message-Id: <202011030117.0A31HjjR042275@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: Conrad Meyer Date: Tue, 3 Nov 2020 01:17:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r367287 - in head: share/man/man4 sys/kern sys/sys X-SVN-Group: head X-SVN-Commit-Author: cem X-SVN-Commit-Paths: in head: share/man/man4 sys/kern sys/sys X-SVN-Commit-Revision: 367287 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Nov 2020 01:17:46 -0000 Author: cem Date: Tue Nov 3 01:17:45 2020 New Revision: 367287 URL: https://svnweb.freebsd.org/changeset/base/367287 Log: unix(4): Add SOL_LOCAL:LOCAL_CREDS_PERSISTENT This option is intended to be semantically identical to Linux's SOL_SOCKET:SO_PASSCRED. For now, it is mutually exclusive with the pre-existing sockopt SOL_LOCAL:LOCAL_CREDS. Reviewed by: markj (penultimate version) Differential Revision: https://reviews.freebsd.org/D27011 Modified: head/share/man/man4/unix.4 head/sys/kern/uipc_usrreq.c head/sys/sys/un.h head/sys/sys/unpcb.h Modified: head/share/man/man4/unix.4 ============================================================================== --- head/share/man/man4/unix.4 Tue Nov 3 01:10:27 2020 (r367286) +++ head/share/man/man4/unix.4 Tue Nov 3 01:17:45 2020 (r367287) @@ -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 @@ which can be set with .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 @@ such as error messages. 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 Modified: head/sys/kern/uipc_usrreq.c ============================================================================== --- head/sys/kern/uipc_usrreq.c Tue Nov 3 01:10:27 2020 (r367286) +++ head/sys/kern/uipc_usrreq.c Tue Nov 3 01:17:45 2020 (r367287) @@ -1040,7 +1040,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m 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 @@ uipc_send(struct socket *so, int flags, struct mbuf *m 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 @@ uipc_ctloutput(struct socket *so, struct sockopt *sopt 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 @@ uipc_ctloutput(struct socket *so, struct sockopt *sopt 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 @@ unp_copy_peercred(struct thread *td, struct unpcb *cli 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_print_unpflags(int unp_flags) 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) { Modified: head/sys/sys/un.h ============================================================================== --- head/sys/sys/un.h Tue Nov 3 01:10:27 2020 (r367286) +++ head/sys/sys/un.h Tue Nov 3 01:17:45 2020 (r367287) @@ -67,6 +67,7 @@ struct sockaddr_un { /* 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. */ Modified: head/sys/sys/unpcb.h ============================================================================== --- head/sys/sys/unpcb.h Tue Nov 3 01:10:27 2020 (r367286) +++ head/sys/sys/unpcb.h Tue Nov 3 01:17:45 2020 (r367287) @@ -107,9 +107,12 @@ struct unpcb { * 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()