git: bd9e3fcaa064 - stable/14 - MAC/do: Fix jail_get() (PR_METHOD_GET)

From: Olivier Certner <olce_at_FreeBSD.org>
Date: Thu, 03 Apr 2025 19:32:12 UTC
The branch stable/14 has been updated by olce:

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

commit bd9e3fcaa064779618353cb45fd03d2d5c66a804
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2024-07-03 15:22:28 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-04-03 19:31:00 +0000

    MAC/do: Fix jail_get() (PR_METHOD_GET)
    
    - Properly fill 'jsys' before copying it out (we would leak bytes from
      the kernel stack).  When the current jail has its own 'struct rules',
      set it to the special value JAIL_SYS_DISABLE if it in fact holds no
      rules.
    - Don't forget to unlock the jail holding rules on error.
    - Correctly return errors.
    
    Reviewed by:    bapt
    Approved by:    markj (mentor)
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D47609
    
    (cherry picked from commit 2a20ce91dc29e5a80f4eeb9352cf3169cd1891b9)
---
 sys/security/mac_do/mac_do.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/sys/security/mac_do/mac_do.c b/sys/security/mac_do/mac_do.c
index 6f68a6f62a79..2482221e43a3 100644
--- a/sys/security/mac_do/mac_do.c
+++ b/sys/security/mac_do/mac_do.c
@@ -353,22 +353,28 @@ mac_do_jail_create(void *obj, void *data __unused)
 static int
 mac_do_jail_get(void *obj, void *data)
 {
-	struct prison *ppr, *pr = obj;
-	struct vfsoptlist *opts = data;
+	struct prison *ppr, *const pr = obj;
+	struct vfsoptlist *const opts = data;
 	struct rules *rules;
 	int jsys, error;
 
 	rules = find_rules(pr, &ppr);
+
+	jsys = pr == ppr ?
+	    (TAILQ_EMPTY(&rules->head) ? JAIL_SYS_DISABLE : JAIL_SYS_NEW) :
+	    JAIL_SYS_INHERIT;
 	error = vfs_setopt(opts, "mac.do", &jsys, sizeof(jsys));
 	if (error != 0 && error != ENOENT)
 		goto done;
+
 	error = vfs_setopts(opts, "mac.do.rules", rules->string);
 	if (error != 0 && error != ENOENT)
 		goto done;
-	prison_unlock(ppr);
+
 	error = 0;
 done:
-	return (0);
+	prison_unlock(ppr);
+	return (error);
 }
 
 static int