Commit ab263f47c9781a644de8b28013434b645082922e
Committed by
Al Viro
1 parent
207032051a
Exists in
master
and in
39 other branches
audit: Use rcu for task lookup protection
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: Al Viro <viro@zeniv.linux.org.uk>
Showing 1 changed file with 14 additions and 16 deletions Side-by-side Diff
kernel/audit.c
... | ... | @@ -873,17 +873,16 @@ |
873 | 873 | case AUDIT_TTY_GET: { |
874 | 874 | struct audit_tty_status s; |
875 | 875 | struct task_struct *tsk; |
876 | + unsigned long flags; | |
876 | 877 | |
877 | - read_lock(&tasklist_lock); | |
878 | + rcu_read_lock(); | |
878 | 879 | tsk = find_task_by_vpid(pid); |
879 | - if (!tsk) | |
880 | - err = -ESRCH; | |
881 | - else { | |
882 | - spin_lock_irq(&tsk->sighand->siglock); | |
880 | + if (tsk && lock_task_sighand(tsk, &flags)) { | |
883 | 881 | s.enabled = tsk->signal->audit_tty != 0; |
884 | - spin_unlock_irq(&tsk->sighand->siglock); | |
885 | - } | |
886 | - read_unlock(&tasklist_lock); | |
882 | + unlock_task_sighand(tsk, &flags); | |
883 | + } else | |
884 | + err = -ESRCH; | |
885 | + rcu_read_unlock(); | |
887 | 886 | |
888 | 887 | if (!err) |
889 | 888 | audit_send_reply(NETLINK_CB(skb).pid, seq, |
890 | 889 | |
891 | 890 | |
892 | 891 | |
... | ... | @@ -893,22 +892,21 @@ |
893 | 892 | case AUDIT_TTY_SET: { |
894 | 893 | struct audit_tty_status *s; |
895 | 894 | struct task_struct *tsk; |
895 | + unsigned long flags; | |
896 | 896 | |
897 | 897 | if (nlh->nlmsg_len < sizeof(struct audit_tty_status)) |
898 | 898 | return -EINVAL; |
899 | 899 | s = data; |
900 | 900 | if (s->enabled != 0 && s->enabled != 1) |
901 | 901 | return -EINVAL; |
902 | - read_lock(&tasklist_lock); | |
902 | + rcu_read_lock(); | |
903 | 903 | tsk = find_task_by_vpid(pid); |
904 | - if (!tsk) | |
905 | - err = -ESRCH; | |
906 | - else { | |
907 | - spin_lock_irq(&tsk->sighand->siglock); | |
904 | + if (tsk && lock_task_sighand(tsk, &flags)) { | |
908 | 905 | tsk->signal->audit_tty = s->enabled != 0; |
909 | - spin_unlock_irq(&tsk->sighand->siglock); | |
910 | - } | |
911 | - read_unlock(&tasklist_lock); | |
906 | + unlock_task_sighand(tsk, &flags); | |
907 | + } else | |
908 | + err = -ESRCH; | |
909 | + rcu_read_unlock(); | |
912 | 910 | break; |
913 | 911 | } |
914 | 912 | default: |