git: 53d2e0d48549 - main - MAC/do: sysctl_rules(): Set the requesting's thread's jail's rules

From: Olivier Certner <olce_at_FreeBSD.org>
Date: Mon, 16 Dec 2024 14:45:48 UTC
The branch main has been updated by olce:

URL: https://cgit.FreeBSD.org/src/commit/?id=53d2e0d4854997005271ee60791ab114bd6e0099

commit 53d2e0d4854997005271ee60791ab114bd6e0099
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2024-07-03 12:59:12 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2024-12-16 14:42:35 +0000

    MAC/do: sysctl_rules(): Set the requesting's thread's jail's rules
    
    Allowing to change the rules specification on a jail other than the
    requesting's thread one is a security issue, as it will immediately
    apply to the jail we inherited from and all its other descendants that
    inherit from it.
    
    With this change, setting the 'mdo_rules' sysctl in a jail forces that
    jail to no more inherit from its parent.
    
    Reviewed by:    bapt
    Approved by:    markj (mentor)
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D47601
---
 sys/security/mac_do/mac_do.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/sys/security/mac_do/mac_do.c b/sys/security/mac_do/mac_do.c
index 94fe7b99fc9d..98bace7052f6 100644
--- a/sys/security/mac_do/mac_do.c
+++ b/sys/security/mac_do/mac_do.c
@@ -310,11 +310,12 @@ static int
 sysctl_rules(SYSCTL_HANDLER_ARGS)
 {
 	char *const buf = malloc(MAC_RULE_STRING_LEN, M_DO, M_WAITOK);
+	struct prison *const td_pr = req->td->td_ucred->cr_prison;
 	struct prison *pr;
 	struct rules *rules;
 	int error;
 
-	rules = find_rules(req->td->td_ucred->cr_prison, &pr);
+	rules = find_rules(td_pr, &pr);
 	strlcpy(buf, rules->string, MAC_RULE_STRING_LEN);
 	prison_unlock(pr);
 
@@ -322,7 +323,8 @@ sysctl_rules(SYSCTL_HANDLER_ARGS)
 	if (error != 0 || req->newptr == NULL)
 		goto out;
 
-	error = parse_and_set_rules(pr, buf);
+	/* Set our prison's rules, not that of the jail we inherited from. */
+	error = parse_and_set_rules(td_pr, buf);
 out:
 	free(buf, M_DO);
 	return (error);