Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145860651
D54992.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D54992.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D54992: kern: better hierarchical jail semantics for ALLOW_UNPRIV_PARENT_TAMPER
Attached
Detach File
Event Timeline
Log In to Comment