lkml.org 
[lkml]   [2008]   [Mar]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] selinux: remove ptrace_sid
Date
This changes checks related to ptrace to get rid of the ptrace_sid
tracking. It's good to disentangle the security model from the
ptrace implementation internals. It's sufficient to check against
the SID of the ptracer at the time a tracee attempts a transition.

Signed-off-by: Roland McGrath <roland@redhat.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
---
security/selinux/hooks.c | 71 ++++++++++++++++++++++++------------
security/selinux/include/objsec.h | 1 -
2 files changed, 47 insertions(+), 25 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 41a049f..ef9eb7e 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -162,7 +162,7 @@ static int task_alloc_security(struct task_struct *task)
return -ENOMEM;

tsec->task = task;
- tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED;
+ tsec->osid = tsec->sid = SECINITSID_UNLABELED;
task->security = tsec;

return 0;
@@ -1638,19 +1638,13 @@ static inline u32 file_to_av(struct file *file)

static int selinux_ptrace(struct task_struct *parent, struct task_struct *child)
{
- struct task_security_struct *psec = parent->security;
- struct task_security_struct *csec = child->security;
int rc;

rc = secondary_ops->ptrace(parent,child);
if (rc)
return rc;

- rc = task_has_perm(parent, child, PROCESS__PTRACE);
- /* Save the SID of the tracing process for later use in apply_creds. */
- if (!(child->ptrace & PT_PTRACED) && !rc)
- csec->ptrace_sid = psec->sid;
- return rc;
+ return task_has_perm(parent, child, PROCESS__PTRACE);
}

static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
@@ -1872,6 +1866,22 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
return __vm_enough_memory(mm, pages, cap_sys_admin);
}

+/**
+ * task_tracer_task - return the task that is tracing the given task
+ * @task: task to consider
+ *
+ * Returns NULL if noone is tracing @task, or the &struct task_struct
+ * pointer to its tracer.
+ *
+ * Must be called under rcu_read_lock().
+ */
+static struct task_struct *task_tracer_task(struct task_struct *task)
+{
+ if (task->ptrace & PT_PTRACED)
+ return rcu_dereference(task->parent);
+ return NULL;
+}
+
/* binprm security operations */

static int selinux_bprm_alloc_security(struct linux_binprm *bprm)
@@ -2119,12 +2129,25 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
/* Check for ptracing, and update the task SID if ok.
Otherwise, leave SID unchanged and kill. */
if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
- rc = avc_has_perm(tsec->ptrace_sid, sid,
- SECCLASS_PROCESS, PROCESS__PTRACE,
- NULL);
- if (rc) {
- bsec->unsafe = 1;
- return;
+ struct task_struct *tracer;
+ struct task_security_struct *sec;
+ u32 ptsid = 0;
+
+ rcu_read_lock();
+ tracer = task_tracer_task(current);
+ if (likely(tracer != NULL)) {
+ sec = tracer->security;
+ ptsid = sec->sid;
+ }
+ rcu_read_unlock();
+
+ if (ptsid != 0) {
+ rc = avc_has_perm(ptsid, sid, SECCLASS_PROCESS,
+ PROCESS__PTRACE, NULL);
+ if (rc) {
+ bsec->unsafe = 1;
+ return;
+ }
}
}
tsec->sid = sid;
@@ -3080,11 +3103,6 @@ static int selinux_task_alloc_security(struct task_struct *tsk)
tsec2->keycreate_sid = tsec1->keycreate_sid;
tsec2->sockcreate_sid = tsec1->sockcreate_sid;

- /* Retain ptracer SID across fork, if any.
- This will be reset by the ptrace hook upon any
- subsequent ptrace_attach operations. */
- tsec2->ptrace_sid = tsec1->ptrace_sid;
-
return 0;
}

@@ -5050,6 +5068,7 @@ static int selinux_setprocattr(struct task_struct *p,
char *name, void *value, size_t size)
{
struct task_security_struct *tsec;
+ struct task_struct *tracer;
u32 sid = 0;
int error;
char *str = value;
@@ -5138,18 +5157,24 @@ static int selinux_setprocattr(struct task_struct *p,
/* Check for ptracing, and update the task SID if ok.
Otherwise, leave SID unchanged and fail. */
task_lock(p);
- if (p->ptrace & PT_PTRACED) {
- error = avc_has_perm_noaudit(tsec->ptrace_sid, sid,
+ rcu_read_lock();
+ tracer = task_tracer_task(p);
+ if (tracer != NULL) {
+ struct task_security_struct *ptsec = tracer->security;
+ u32 ptsid = ptsec->sid;
+ rcu_read_unlock();
+ error = avc_has_perm_noaudit(ptsid, sid,
SECCLASS_PROCESS,
PROCESS__PTRACE, 0, &avd);
if (!error)
tsec->sid = sid;
task_unlock(p);
- avc_audit(tsec->ptrace_sid, sid, SECCLASS_PROCESS,
+ avc_audit(ptsid, sid, SECCLASS_PROCESS,
PROCESS__PTRACE, &avd, error, NULL);
if (error)
return error;
} else {
+ rcu_read_unlock();
tsec->sid = sid;
task_unlock(p);
}
@@ -5624,5 +5649,3 @@ int selinux_disable(void)
return 0;
}
#endif
-
-
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index c6c2bb4..1db31c2 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -35,7 +35,6 @@ struct task_security_struct {
u32 create_sid; /* fscreate SID */
u32 keycreate_sid; /* keycreate SID */
u32 sockcreate_sid; /* fscreate SID */
- u32 ptrace_sid; /* SID of ptrace parent */
};

struct inode_security_struct {

\
 
 \ /
  Last update: 2008-03-26 23:49    [W:0.038 / U:0.496 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site