| From 378cc63c24b6c9b9269c05475fbefeb8335790b3 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> |
| |
| diff --git a/kernel/audit.c b/kernel/audit.c |
| index bf307dd..8ccf8d5 100644 |
| --- a/kernel/audit.c |
| +++ b/kernel/audit.c |
| @@ -880,17 +880,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, |
| @@ -900,22 +899,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.1.1 |
| |