Page MenuHomeFreeBSD

D54992.diff
No OneTemporary

D54992.diff

diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -3334,6 +3334,30 @@
return ((cred->cr_prison->pr_allow & flag) != 0);
}
+/*
+ * See if the specific allow flag is set on every jail between the child cred2
+ * and parent cred1. This obviously could be a little racey because we're
+ * clearly not going to have locked every prison in the given path, but the
+ * common case is a single prison belonging to the child and we're only checking
+ * a single bit without regard to any other prison data.
+ */
+bool
+prison_chain_allow(struct ucred *cred1, struct ucred *cred2, unsigned flag)
+{
+ struct prison *ppr;
+
+ MPASS(prison_check(cred1, cred2) == 0);
+ for (ppr = cred2->cr_prison; ppr != cred1->cr_prison;
+ ppr = ppr->pr_parent) {
+ /* prison_check() failed us? */
+ MPASS(ppr != NULL);
+ if ((ppr->pr_allow & flag) == 0)
+ return (false);
+ }
+
+ return (true);
+}
+
/*
* Hold a prison reference, by incrementing pr_ref. It is generally
* an error to hold a prison that does not already have a reference.
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1970,8 +1970,15 @@
* all that would control an unprivileged process' ability to tamper
* with a process in a subjail by default if we did not have the
* allow.unprivileged_parent_tampering knob to restrict it by default.
+ *
+ * We use the chain semantics here to allow hierarchical jails to do
+ * the right thing: given jails `foo` and `foo.bar`, if `foo` doesn't
+ * allow its parent to do unprivileged tampering but `foo.bar` does,
+ * then we should only allow `foo` unprivileged processes to tamper with
+ * `foo.bar` -- not unjailed unpriv. Basically: one should not tamper
+ * across a noallow boundary.
*/
- if (prison_allow(u2, PR_ALLOW_UNPRIV_PARENT_TAMPER))
+ if (prison_chain_allow(u1, u2, PR_ALLOW_UNPRIV_PARENT_TAMPER))
return (0);
return (EPERM);
diff --git a/sys/sys/jail.h b/sys/sys/jail.h
--- a/sys/sys/jail.h
+++ b/sys/sys/jail.h
@@ -457,6 +457,7 @@
void getjailname(struct ucred *cred, char *name, size_t len);
void prison0_init(void);
bool prison_allow(struct ucred *, unsigned);
+bool prison_chain_allow(struct ucred *cred1, struct ucred *cred2, unsigned);
int prison_check(struct ucred *cred1, struct ucred *cred2);
bool prison_check_nfsd(struct ucred *cred);
bool prison_owns_vnet(struct prison *pr);

File Metadata

Mime Type
text/plain
Expires
Thu, Feb 26, 8:32 AM (3 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29002918
Default Alt Text
D54992.diff (2 KB)

Event Timeline