From: Kees Cook on 13 Jul 2010 13:40 This cleans up the ancestry check by separating it out into its own function, which makes the code a bit more readable. Additionally, it now checks for and uses the thread group leader since otherwise we may end up missing potential matches on attaches to threads. Signed-off-by: Kees Cook <kees.cook(a)canonical.com> --- security/yama/yama_lsm.c | 55 ++++++++++++++++++++++++++++++++------------- 1 files changed, 39 insertions(+), 16 deletions(-) diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 72929d2..3b76386 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -21,6 +21,40 @@ static int protected_sticky_symlinks = 1; static int protected_nonaccess_hardlinks = 1; /** + * task_is_descendant - walk up a process family tree looking for a match + * @parent: the process to compare against while walking up from child + * @child: the process to start from while looking upwards for parent + * + * Returns 1 if child is a descendant of parent, 0 if not. + */ +static int task_is_descendant(struct task_struct *parent, + struct task_struct *child) +{ + int rc = 0; + struct task_struct *walker = child; + + if (!parent || !child) + return 0; + + rcu_read_lock(); + read_lock(&tasklist_lock); + while (walker->pid > 0) { + if (!thread_group_leader(walker)) + walker = walker->group_leader; + if (walker == parent) { + rc = 1; + break; + } + walker = walker->real_parent; + } + read_unlock(&tasklist_lock); + rcu_read_unlock(); + + return rc; +} + + +/** * yama_ptrace_access_check - validate PTRACE_ATTACH calls * @child: child task pointer * @mode: ptrace attach mode @@ -37,22 +71,11 @@ static int yama_ptrace_access_check(struct task_struct *child, return rc; /* require ptrace target be a child of ptracer on attach */ - if (mode == PTRACE_MODE_ATTACH && ptrace_scope && - !capable(CAP_SYS_PTRACE)) { - struct task_struct *walker = child; - - rcu_read_lock(); - read_lock(&tasklist_lock); - while (walker->pid > 0) { - if (walker == current) - break; - walker = walker->real_parent; - } - if (walker->pid == 0) - rc = -EPERM; - read_unlock(&tasklist_lock); - rcu_read_unlock(); - } + if (mode == PTRACE_MODE_ATTACH && + ptrace_scope && + !task_is_descendant(current, child) && + !capable(CAP_SYS_PTRACE)) + rc = -EPERM; if (rc) { char name[sizeof(current->comm)]; -- 1.7.1 -- Kees Cook Ubuntu Security Team -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|
Pages: 1 Prev: [PATCH] input: Add pwm beeper driver Next: [GIT PULL] KVM updates for 2.6.35-rc4 |