The branch main has been updated by kevans:

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

commit d7a517eb6d770e22db6a46a46677db27f565767c
Author:     Kyle Evans <[email protected]>
AuthorDate: 2025-10-26 01:42:30 +0000
Commit:     Kyle Evans <[email protected]>
CommitDate: 2026-01-16 00:23:39 +0000

    jaildesc: add an accessor for the struct prison in a jaildesc
    
    We'll subsequently use this in the MAC framework to get a struct prison
    when we already have the struct file in question, rather than an fd.
    
    Reviewed by:    jamie, olce
    Differential Revision:  https://reviews.freebsd.org/D53955
---
 sys/kern/kern_jaildesc.c | 77 +++++++++++++++++++++++++++++++++++-------------
 sys/sys/jaildesc.h       |  1 +
 2 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/sys/kern/kern_jaildesc.c b/sys/kern/kern_jaildesc.c
index f4e31801201f..80d0f3d07d7c 100644
--- a/sys/kern/kern_jaildesc.c
+++ b/sys/kern/kern_jaildesc.c
@@ -72,42 +72,66 @@ static const struct fileops jaildesc_ops = {
 };
 
 /*
- * Given a jail descriptor number, return its prison and/or its
- * credential.  They are returned held, and will need to be released
- * by the caller.
+ * Retrieve a prison from a jail descriptor.  If prp is not NULL, then the
+ * prison will be held and subsequently returned, and must be released by the
+ * caller.  This differs from jaildesc_get_prison in that it doesn't actually
+ * require the caller to take the struct prison, which we use internally when
+ * the caller doesn't necessarily need it- it might just want to check 
validity.
  */
-int
-jaildesc_find(struct thread *td, int fd, struct prison **prp,
-    struct ucred **ucredp)
+static int
+jaildesc_get_prison_impl(struct file *fp, struct prison **prp)
 {
-       struct file *fp;
-       struct jaildesc *jd;
        struct prison *pr;
-       int error;
+       struct jaildesc *jd;
+
+       if (fp->f_type != DTYPE_JAILDESC)
+               return (EINVAL);
 
-       error = fget(td, fd, &cap_no_rights, &fp);
-       if (error != 0)
-               return (error);
-       if (fp->f_type != DTYPE_JAILDESC) {
-               error = EINVAL;
-               goto out;
-       }
        jd = fp->f_data;
        JAILDESC_LOCK(jd);
        pr = jd->jd_prison;
        if (pr == NULL || !prison_isvalid(pr)) {
-               error = ENOENT;
                JAILDESC_UNLOCK(jd);
-               goto out;
+               return (ENOENT);
        }
+
        if (prp != NULL) {
                prison_hold(pr);
                *prp = pr;
        }
+
        JAILDESC_UNLOCK(jd);
-       if (ucredp != NULL)
-               *ucredp = crhold(fp->f_cred);
- out:
+
+       return (0);
+}
+
+/*
+ * Given a jail descriptor number, return its prison and/or its
+ * credential.  They are returned held, and will need to be released
+ * by the caller.
+ */
+int
+jaildesc_find(struct thread *td, int fd, struct prison **prp,
+    struct ucred **ucredp)
+{
+       struct file *fp;
+       int error;
+
+       error = fget(td, fd, &cap_no_rights, &fp);
+       if (error != 0)
+               return (error);
+
+       error = jaildesc_get_prison_impl(fp, prp);
+       if (error == 0) {
+               /*
+                * jaildesc_get_prison validated the file and held the prison
+                * for us if the caller wants it, so we just need to grab the
+                * ucred on the way out.
+                */
+               if (ucredp != NULL)
+                       *ucredp = crhold(fp->f_cred);
+       }
+
        fdrop(fp, td);
        return (error);
 }
@@ -145,6 +169,17 @@ jaildesc_alloc(struct thread *td, struct file **fpp, int 
*fdp, int owning)
        return (0);
 }
 
+/*
+ * Retrieve a prison from a jail descriptor.  It will be returned held, and 
must
+ * be released by the caller.
+ */
+int
+jaildesc_get_prison(struct file *fp, struct prison **prp)
+{
+       MPASS(prp != NULL);
+       return (jaildesc_get_prison_impl(fp, prp));
+}
+
 /*
  * Assocate a jail descriptor with its prison.
  */
diff --git a/sys/sys/jaildesc.h b/sys/sys/jaildesc.h
index fda270d62e70..b0a1a6238cc9 100644
--- a/sys/sys/jaildesc.h
+++ b/sys/sys/jaildesc.h
@@ -78,6 +78,7 @@ struct jaildesc {
 int jaildesc_find(struct thread *td, int fd, struct prison **prp,
     struct ucred **ucredp);
 int jaildesc_alloc(struct thread *td, struct file **fpp, int *fdp, int owning);
+int jaildesc_get_prison(struct file *jd, struct prison **prp);
 void jaildesc_set_prison(struct file *jd, struct prison *pr);
 void jaildesc_prison_cleanup(struct prison *pr);
 void jaildesc_knote(struct prison *pr, long hint);

Reply via email to