git: d7a517eb6d77 - main - jaildesc: add an accessor for the struct prison in a jaildesc
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 16 Jan 2026 00:24:20 UTC
The branch main has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=d7a517eb6d770e22db6a46a46677db27f565767c
commit d7a517eb6d770e22db6a46a46677db27f565767c
Author: Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-10-26 01:42:30 +0000
Commit: Kyle Evans <kevans@FreeBSD.org>
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);