Page MenuHomeFreeBSD

D53955.id.diff
No OneTemporary

D53955.id.diff

diff --git a/sys/kern/kern_jaildesc.c b/sys/kern/kern_jaildesc.c
--- a/sys/kern/kern_jaildesc.c
+++ b/sys/kern/kern_jaildesc.c
@@ -72,42 +72,66 @@
};
/*
- * 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 @@
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
--- a/sys/sys/jaildesc.h
+++ b/sys/sys/jaildesc.h
@@ -78,6 +78,7 @@
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);

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 28, 11:26 AM (2 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32254704
Default Alt Text
D53955.id.diff (3 KB)

Event Timeline