@@ -213,6 +213,7 @@ static void cred_init_security(void)
panic("SELinux: Failed to initialize initial task.\n");
tsec->osid = tsec->sid = SECINITSID_KERNEL;
+ tsec->ns = get_selinux_ns(init_selinux_ns);
cred->security = tsec;
}
@@ -227,15 +228,35 @@ static inline u32 cred_sid(const struct cred *cred)
return tsec->sid;
}
+static struct task_security_struct unlabeled_task_security = {
+ .osid = SECINITSID_UNLABELED,
+ .sid = SECINITSID_UNLABELED,
+};
+
+static const struct task_security_struct *task_security(
+ const struct task_struct *p)
+{
+ const struct task_security_struct *tsec;
+
+ tsec = __task_cred(p)->security;
+ while (tsec->ns != current_selinux_ns && tsec->parent_cred)
+ tsec = tsec->parent_cred->security;
+ if (tsec->ns != current_selinux_ns)
+ return &unlabeled_task_security;
+ return tsec;
+}
+
/*
* get the objective security ID of a task
*/
static inline u32 task_sid(const struct task_struct *task)
{
+ const struct task_security_struct *tsec;
u32 sid;
rcu_read_lock();
- sid = cred_sid(__task_cred(task));
+ tsec = task_security(task);
+ sid = tsec->sid;
rcu_read_unlock();
return sid;
}
@@ -3900,6 +3921,9 @@ static void selinux_cred_free(struct cred *cred)
*/
BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE);
cred->security = (void *) 0x7UL;
+ put_selinux_ns(tsec->ns);
+ if (tsec->parent_cred)
+ put_cred(tsec->parent_cred);
kfree(tsec);
}
@@ -3918,6 +3942,9 @@ static int selinux_cred_prepare(struct cred *new, const struct cred *old,
if (!tsec)
return -ENOMEM;
+ tsec->ns = get_selinux_ns(old_tsec->ns);
+ if (old_tsec->parent_cred)
+ tsec->parent_cred = get_cred(old_tsec->parent_cred);
new->security = tsec;
return 0;
}
@@ -3931,6 +3958,9 @@ static void selinux_cred_transfer(struct cred *new, const struct cred *old)
struct task_security_struct *tsec = new->security;
*tsec = *old_tsec;
+ tsec->ns = get_selinux_ns(old_tsec->ns);
+ if (old_tsec->parent_cred)
+ tsec->parent_cred = get_cred(old_tsec->parent_cred);
}
/*
@@ -6054,7 +6084,7 @@ static int selinux_getprocattr(struct task_struct *p,
unsigned len;
rcu_read_lock();
- __tsec = __task_cred(p)->security;
+ __tsec = task_security(p);
if (current != p) {
error = avc_has_perm(current_selinux_ns,
@@ -29,15 +29,6 @@
#include "flask.h"
#include "avc.h"
-struct task_security_struct {
- u32 osid; /* SID prior to last execve */
- u32 sid; /* current SID */
- u32 exec_sid; /* exec SID */
- u32 create_sid; /* fscreate SID */
- u32 keycreate_sid; /* keycreate SID */
- u32 sockcreate_sid; /* fscreate SID */
-};
-
/*
* get the subjective security ID of the current task
*/
@@ -133,7 +133,18 @@ static inline struct selinux_ns *get_selinux_ns(struct selinux_ns *ns)
extern struct selinux_ns *init_selinux_ns;
-#define current_selinux_ns (init_selinux_ns)
+struct task_security_struct {
+ u32 osid; /* SID prior to last execve */
+ u32 sid; /* current SID */
+ u32 exec_sid; /* exec SID */
+ u32 create_sid; /* fscreate SID */
+ u32 keycreate_sid; /* keycreate SID */
+ u32 sockcreate_sid; /* fscreate SID */
+ struct selinux_ns *ns; /* selinux namespace */
+ const struct cred *parent_cred; /* cred in parent ns */
+};
+
+#define current_selinux_ns (((struct task_security_struct *)current_security())->ns)
#define ss_initialized (current_selinux_ns->initialized)