| From 4aa96a9261e3541c6ca36e6081be1d08a52f4c78 Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Wed, 9 Dec 2009 14:33:48 +0100 |
| Subject: [PATCH] audit: Use rcu for task lookup protection |
| |
| commit 378cc63c24b6c9b9269c05475fbefeb8335790b3 in tip. |
| |
| Protect the task lookups in audit_receive_msg() with rcu_read_lock() |
| instead of tasklist_lock and use lock/unlock_sighand to protect |
| against the exit race. |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Cc: Al Viro <viro@zeniv.linux.org.uk> |
| Cc: Eric Paris <eparis@redhat.com> |
| Cc: Oleg Nesterov <oleg@redhat.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| kernel/audit.c | 30 ++++++++++++++---------------- |
| 1 files changed, 14 insertions(+), 16 deletions(-) |
| |
| diff --git a/kernel/audit.c b/kernel/audit.c |
| index 3d04a64..4ac4746 100644 |
| --- a/kernel/audit.c |
| +++ b/kernel/audit.c |
| @@ -881,17 +881,16 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
| case AUDIT_TTY_GET: { |
| struct audit_tty_status s; |
| struct task_struct *tsk; |
| + unsigned long flags; |
| |
| - read_lock(&tasklist_lock); |
| + rcu_read_lock(); |
| tsk = find_task_by_vpid(pid); |
| - if (!tsk) |
| - err = -ESRCH; |
| - else { |
| - spin_lock_irq(&tsk->sighand->siglock); |
| + if (tsk && lock_task_sighand(tsk, &flags)) { |
| s.enabled = tsk->signal->audit_tty != 0; |
| - spin_unlock_irq(&tsk->sighand->siglock); |
| - } |
| - read_unlock(&tasklist_lock); |
| + unlock_task_sighand(tsk, &flags); |
| + } else |
| + err = -ESRCH; |
| + rcu_read_unlock(); |
| |
| if (!err) |
| audit_send_reply(NETLINK_CB(skb).pid, seq, |
| @@ -901,22 +900,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
| case AUDIT_TTY_SET: { |
| struct audit_tty_status *s; |
| struct task_struct *tsk; |
| + unsigned long flags; |
| |
| if (nlh->nlmsg_len < sizeof(struct audit_tty_status)) |
| return -EINVAL; |
| s = data; |
| if (s->enabled != 0 && s->enabled != 1) |
| return -EINVAL; |
| - read_lock(&tasklist_lock); |
| + rcu_read_lock(); |
| tsk = find_task_by_vpid(pid); |
| - if (!tsk) |
| - err = -ESRCH; |
| - else { |
| - spin_lock_irq(&tsk->sighand->siglock); |
| + if (tsk && lock_task_sighand(tsk, &flags)) { |
| tsk->signal->audit_tty = s->enabled != 0; |
| - spin_unlock_irq(&tsk->sighand->siglock); |
| - } |
| - read_unlock(&tasklist_lock); |
| + unlock_task_sighand(tsk, &flags); |
| + } else |
| + err = -ESRCH; |
| + rcu_read_unlock(); |
| break; |
| } |
| default: |
| -- |
| 1.7.0.4 |
| |