diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2009-12-09 09:19:31 -0500 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-10-30 08:45:25 -0400 |
| commit | 3c80fe4ac9cfb13b1bfa4edf1544e8b656716694 (patch) | |
| tree | c605435b642323cd76eea9567a43d8c67b9c9db1 /include/linux | |
| parent | f7a998a9491f2da1d3e44d150aa611d10093da4f (diff) | |
audit: Call tty_audit_push_task() outside preempt disabled
While auditing all tasklist_lock read_lock sites I stumbled over the
following call chain:
audit_prepare_user_tty()
read_lock(&tasklist_lock);
tty_audit_push_task();
mutex_lock(&buf->mutex);
--> buf->mutex is locked with preemption disabled.
Solve this by acquiring a reference to the task struct under
rcu_read_lock and call tty_audit_push_task outside of the preempt
disabled region.
Move all code which needs to be protected by sighand lock into
tty_audit_push_task() and use lock/unlock_sighand as we do not hold
tasklist_lock.
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>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/tty.h | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/include/linux/tty.h b/include/linux/tty.h index e500171c745f..2a754748dd5f 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
| @@ -541,8 +541,8 @@ extern void tty_audit_exit(void); | |||
| 541 | extern void tty_audit_fork(struct signal_struct *sig); | 541 | extern void tty_audit_fork(struct signal_struct *sig); |
| 542 | extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); | 542 | extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); |
| 543 | extern void tty_audit_push(struct tty_struct *tty); | 543 | extern void tty_audit_push(struct tty_struct *tty); |
| 544 | extern void tty_audit_push_task(struct task_struct *tsk, | 544 | extern int tty_audit_push_task(struct task_struct *tsk, |
| 545 | uid_t loginuid, u32 sessionid); | 545 | uid_t loginuid, u32 sessionid); |
| 546 | #else | 546 | #else |
| 547 | static inline void tty_audit_add_data(struct tty_struct *tty, | 547 | static inline void tty_audit_add_data(struct tty_struct *tty, |
| 548 | unsigned char *data, size_t size) | 548 | unsigned char *data, size_t size) |
| @@ -560,9 +560,10 @@ static inline void tty_audit_fork(struct signal_struct *sig) | |||
| 560 | static inline void tty_audit_push(struct tty_struct *tty) | 560 | static inline void tty_audit_push(struct tty_struct *tty) |
| 561 | { | 561 | { |
| 562 | } | 562 | } |
| 563 | static inline void tty_audit_push_task(struct task_struct *tsk, | 563 | static inline int tty_audit_push_task(struct task_struct *tsk, |
| 564 | uid_t loginuid, u32 sessionid) | 564 | uid_t loginuid, u32 sessionid) |
| 565 | { | 565 | { |
| 566 | return 0; | ||
| 566 | } | 567 | } |
| 567 | #endif | 568 | #endif |
| 568 | 569 | ||
