From nobody Mon Sep 15 17:26:28 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4cQX510Wflz67gFG; Mon, 15 Sep 2025 17:26:29 +0000 (UTC) (envelope-from git@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 "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4cQX506wJYz3sRc; Mon, 15 Sep 2025 17:26:28 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1757957189; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=rBbUeQt8+euoRj3G3Frz5sdlLSZQrGfMkPkbbHcGMtE=; b=ftXWN/CBX+snlVTbe4QVmr9O6gTZ9a2oJca7woC6W55Pa9znTMyFXYMfZ07BF0G9lyKAmA TVgHwla5iOwWc+f/2eOkcwTDxBdpPI4c9vmmCIEpHJIVN46wnzyhew612yeAvYOO79Ze24 3tNW4OAyOP8cllJFgoDovlutiyUt+ruoX+Qz7UG+SRl0USiIEDQNhs1biJgCOxHRb2BRjP MCREx3M3IDRCZ/zBXzd0btEYSI4TRIQEuqa2CsOoeR10hMgklEICmQuzsmk+aR2DxwtRpM yyd3NTA+ecEkWC9rj+9XWKkAf+S/lcDhEEHiL0Pw1mqFyCYpBicw/e2vUgfUzQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1757957189; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=rBbUeQt8+euoRj3G3Frz5sdlLSZQrGfMkPkbbHcGMtE=; b=vBO5i3R3+cTAzWqaEGjHbbABvk3z1yJhsN/Q3ulvIMqz0qyZkEZ+xw3g30IPKbPnUkJX/d mhruZGzQ6Lk7M+u4Ov6fb92weBIkzNTF5VcrUGr8M8Fb9+ymOzsJDosbAHxT5RayYrfdEA b+R2Zu5ly5B0YlFifr2QuxMjRKPPrV7S0bdUxhOUmRev18RZ+4cBiP4BjQWqds24K6TeyX K2DF/gLibt3iiqt+NLcNY8wBc7IfDLp+SF8Vt/sXEyiY1hR9FuDfQecEutPnsyBDjsHPFN 0XqskkcNgL6PtWwmcJWhywKuNEuIwpzI2+pSwgQSxW+sTCexTYZGDY7P3JMEJg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1757957189; a=rsa-sha256; cv=none; b=I3pvNW+89kOjlKdF0Q+cZ75ijTo6Ov889NcP5fpgB54JdJYhWl4OWSI8u6vRM6lQWmVY7g MgD44gynQ3xrmTkrZvImpjdeKuRL2SZE9IUAVpRBihZhFOAKxdIGmo/+Bbyw41sr19DiXh WCk65RccbEzaCRDPP2nLh2lav7N6PzH3DiW5+Obwpo1WiXmTYPaB1IeFZgZ5Iog6pRb/pT ASdzPRLkdq8QM7cw1ghawcqPBJdbQQNdg7P7AqyZTbiYu9eKaJA5rj5bcu2qFRzM9KhVSr CW2Bi6lOOoJnBcFHopXwJ0tNDHAxIU+XOemiTpahvUPyc8cK5EAsKTCCS0ee2A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4cQX506QSqz13Rc; Mon, 15 Sep 2025 17:26:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 58FHQSjk048507; Mon, 15 Sep 2025 17:26:28 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 58FHQSdN048504; Mon, 15 Sep 2025 17:26:28 GMT (envelope-from git) Date: Mon, 15 Sep 2025 17:26:28 GMT Message-Id: <202509151726.58FHQSdN048504@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: 246d7e9fc239 - main - jail: Optionally allow audit session state to be configured in a jail List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 246d7e9fc23928be22db38220f5439f5cdee5264 Auto-Submitted: auto-generated The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=246d7e9fc23928be22db38220f5439f5cdee5264 commit 246d7e9fc23928be22db38220f5439f5cdee5264 Author: Mark Johnston AuthorDate: 2025-09-15 17:23:50 +0000 Commit: Mark Johnston CommitDate: 2025-09-15 17:23:50 +0000 jail: Optionally allow audit session state to be configured in a jail Currently it is impossible for a privileged, jailed process to set audit session state. This can result in suprising audit event misattribution. For example, suppose a user ssh'es into a jail and restarts a service; normally, sshd sets audit state such that events generated by the SSH session are attributed to the newly authenticated user, but in a jail, the corresponding setaudit(2) call fails, so events are attributed to the user who had started sshd in the jail (typically the user who had started the jail itself by some means). While this behaviour is reasonable, administrators might want to trust the jailed sshd to reset audit state, such that the authenticated user appears in audit logs. Add a jail knob to enable this. Add a simple regression test. Reviewed by: kevans, jamie MFC after: 1 week Sponsored by: Modirum MDPay Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D51719 --- sys/kern/kern_jail.c | 13 ++++++++++++- sys/security/audit/audit_syscalls.c | 12 ------------ sys/sys/jail.h | 3 ++- usr.sbin/jail/jail.8 | 19 +++++++++++++++---- usr.sbin/jail/tests/jail_basic_test.sh | 20 ++++++++++++++++++++ 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index a75ba89d2a7e..3697d95fe0e5 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -243,6 +243,9 @@ static struct bool_flags pr_flag_allow[NBBY * NBPW] = { {"allow.unprivileged_parent_tampering", "allow.nounprivileged_parent_tampering", PR_ALLOW_UNPRIV_PARENT_TAMPER}, +#ifdef AUDIT + {"allow.setaudit", "allow.nosetaudit", PR_ALLOW_SETAUDIT}, +#endif }; static unsigned pr_allow_all = PR_ALLOW_ALL_STATIC; const size_t pr_flag_allow_size = sizeof(pr_flag_allow); @@ -4289,7 +4292,6 @@ prison_priv_check(struct ucred *cred, int priv) */ case PRIV_KTRACE: -#if 0 /* * Allow jailed processes to configure audit identity and * submit audit records (login, etc). In the future we may @@ -4298,6 +4300,11 @@ prison_priv_check(struct ucred *cred, int priv) */ case PRIV_AUDIT_GETAUDIT: case PRIV_AUDIT_SETAUDIT: + if (cred->cr_prison->pr_allow & PR_ALLOW_SETAUDIT) + return (0); + else + return (EPERM); +#if 0 case PRIV_AUDIT_SUBMIT: #endif @@ -5034,6 +5041,10 @@ SYSCTL_JAIL_PARAM(_allow, settime, CTLTYPE_INT | CTLFLAG_RW, "B", "Jail may set system time"); SYSCTL_JAIL_PARAM(_allow, routing, CTLTYPE_INT | CTLFLAG_RW, "B", "Jail may modify routing table"); +#ifdef AUDIT +SYSCTL_JAIL_PARAM(_allow, setaudit, CTLTYPE_INT | CTLFLAG_RW, + "B", "Jail may set and get audit session state"); +#endif SYSCTL_JAIL_PARAM_SUBNODE(allow, mount, "Jail mount/unmount permission flags"); SYSCTL_JAIL_PARAM(_allow_mount, , CTLTYPE_INT | CTLFLAG_RW, diff --git a/sys/security/audit/audit_syscalls.c b/sys/security/audit/audit_syscalls.c index 40b2fb3d1c9f..262f2c1ae1e3 100644 --- a/sys/security/audit/audit_syscalls.c +++ b/sys/security/audit/audit_syscalls.c @@ -592,8 +592,6 @@ sys_getauid(struct thread *td, struct getauid_args *uap) { int error; - if (jailed(td->td_ucred)) - return (ENOSYS); error = priv_check(td, PRIV_AUDIT_GETAUDIT); if (error) return (error); @@ -609,8 +607,6 @@ sys_setauid(struct thread *td, struct setauid_args *uap) au_id_t id; int error; - if (jailed(td->td_ucred)) - return (ENOSYS); error = copyin(uap->auid, &id, sizeof(id)); if (error) return (error); @@ -650,8 +646,6 @@ sys_getaudit(struct thread *td, struct getaudit_args *uap) int error; cred = td->td_ucred; - if (jailed(cred)) - return (ENOSYS); error = priv_check(td, PRIV_AUDIT_GETAUDIT); if (error) return (error); @@ -674,8 +668,6 @@ sys_setaudit(struct thread *td, struct setaudit_args *uap) struct auditinfo ai; int error; - if (jailed(td->td_ucred)) - return (ENOSYS); error = copyin(uap->auditinfo, &ai, sizeof(ai)); if (error) return (error); @@ -715,8 +707,6 @@ sys_getaudit_addr(struct thread *td, struct getaudit_addr_args *uap) { int error; - if (jailed(td->td_ucred)) - return (ENOSYS); if (uap->length < sizeof(*uap->auditinfo_addr)) return (EOVERFLOW); error = priv_check(td, PRIV_AUDIT_GETAUDIT); @@ -734,8 +724,6 @@ sys_setaudit_addr(struct thread *td, struct setaudit_addr_args *uap) struct auditinfo_addr aia; int error; - if (jailed(td->td_ucred)) - return (ENOSYS); error = copyin(uap->auditinfo_addr, &aia, sizeof(aia)); if (error) return (error); diff --git a/sys/sys/jail.h b/sys/sys/jail.h index e12e8c3178c9..e6a13e6719dd 100644 --- a/sys/sys/jail.h +++ b/sys/sys/jail.h @@ -271,6 +271,7 @@ struct prison_racct { #define PR_ALLOW_SETTIME 0x00100000 #define PR_ALLOW_ROUTING 0x00200000 #define PR_ALLOW_UNPRIV_PARENT_TAMPER 0x00400000 +#define PR_ALLOW_SETAUDIT 0x00800000 /* * PR_ALLOW_PRISON0 are the allow flags that we apply by default to prison0, @@ -278,7 +279,7 @@ struct prison_racct { * build time. PR_ALLOW_ALL_STATIC should contain any bit above that we expect * to be used on the system, while PR_ALLOW_PRISON0 will be some subset of that. */ -#define PR_ALLOW_ALL_STATIC 0x007f87ff +#define PR_ALLOW_ALL_STATIC 0x00ff87ff #define PR_ALLOW_PRISON0 \ (PR_ALLOW_ALL_STATIC & ~(PR_ALLOW_UNPRIV_PARENT_TAMPER)) diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8 index 421aa9babb4c..d44b7f66a64e 100644 --- a/usr.sbin/jail/jail.8 +++ b/usr.sbin/jail/jail.8 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 7, 2025 +.Dd September 15, 2025 .Dt JAIL 8 .Os .Sh NAME @@ -702,15 +702,15 @@ The super-user will be disabled automatically if its parent system has it disabled. The super-user is enabled by default. .It Va allow.extattr -Allow privileged process in the jail to manipulate filesystem extended +Allow privileged processes in the jail to manipulate filesystem extended attributes in the system namespace. .It Va allow.adjtime -Allow privileged process in the jail to slowly adjusting global operating system +Allow privileged processes in the jail to slowly adjusting global operating system time. For example through utilities like .Xr ntpd 8 . .It Va allow.settime -Allow privileged process in the jail to set global operating system data +Allow privileged processes in the jail to set global operating system data and time. For example through utilities like .Xr date 1 . @@ -719,6 +719,17 @@ This permission includes also .It Va allow.routing Allow privileged process in the non-VNET jail to modify the system routing table. +.It Va allow.setaudit +Allow privileged processes in the jail to set +.Xr audit 4 +session state using +.Xr setaudit 2 +and related system calls. +This is useful, for example, for allowing a jailed +.Xr sshd 8 +to set the audit user ID for an authenticated session. +However, it gives jailed processes the ability to modify or disable audit +session state, so should be configured with care. .El .El .Pp diff --git a/usr.sbin/jail/tests/jail_basic_test.sh b/usr.sbin/jail/tests/jail_basic_test.sh index 6802da7b049a..c781eed78756 100755 --- a/usr.sbin/jail/tests/jail_basic_test.sh +++ b/usr.sbin/jail/tests/jail_basic_test.sh @@ -306,6 +306,25 @@ param_consistency_cleanup() fi } +atf_test_case "setaudit" +setaudit_head() +{ + atf_set descr 'Test that setaudit works in a jail when configured with allow.setaudit' + atf_set require.user root + atf_set require.progs setaudit +} + +setaudit_body() +{ + # Try to modify the audit mask within a jail without + # allow.setaudit configured. + atf_check -s not-exit:0 -o empty -e not-empty jail -c name=setaudit_jail \ + command=setaudit -m fr ls / + # The command should succeed if allow.setaudit is configured. + atf_check -s exit:0 -o ignore -e empty jail -c name=setaudit_jail \ + allow.setaudit command=setaudit -m fr ls / +} + atf_init_test_cases() { atf_add_test_case "basic" @@ -314,4 +333,5 @@ atf_init_test_cases() atf_add_test_case "commands" atf_add_test_case "jid_name_set" atf_add_test_case "param_consistency" + atf_add_test_case "setaudit" }