aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/tty_audit.c38
-rw-r--r--include/linux/tty.h9
-rw-r--r--kernel/audit.c25
3 files changed, 42 insertions, 30 deletions
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c
index 1b8ee590b4ca..f64582b0f623 100644
--- a/drivers/char/tty_audit.c
+++ b/drivers/char/tty_audit.c
@@ -188,25 +188,43 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch)
188} 188}
189 189
190/** 190/**
191 * tty_audit_push_task - Flush task's pending audit data 191 * tty_audit_push_task - Flush task's pending audit data
192 * @tsk: task pointer
193 * @loginuid: sender login uid
194 * @sessionid: sender session id
195 *
196 * Called with a ref on @tsk held. Try to lock sighand and get a
197 * reference to the tty audit buffer if available.
198 * Flush the buffer or return an appropriate error code.
192 */ 199 */
193void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid) 200int tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid)
194{ 201{
195 struct tty_audit_buf *buf; 202 struct tty_audit_buf *buf = ERR_PTR(-EPERM);
203 unsigned long flags;
196 204
197 spin_lock_irq(&tsk->sighand->siglock); 205 if (!lock_task_sighand(tsk, &flags))
198 buf = tsk->signal->tty_audit_buf; 206 return -ESRCH;
199 if (buf) 207
200 atomic_inc(&buf->count); 208 if (tsk->signal->audit_tty) {
201 spin_unlock_irq(&tsk->sighand->siglock); 209 buf = tsk->signal->tty_audit_buf;
202 if (!buf) 210 if (buf)
203 return; 211 atomic_inc(&buf->count);
212 }
213 unlock_task_sighand(tsk, &flags);
214
215 /*
216 * Return 0 when signal->audit_tty set
217 * but tsk->signal->tty_audit_buf == NULL.
218 */
219 if (!buf || IS_ERR(buf))
220 return PTR_ERR(buf);
204 221
205 mutex_lock(&buf->mutex); 222 mutex_lock(&buf->mutex);
206 tty_audit_buf_push(tsk, loginuid, sessionid, buf); 223 tty_audit_buf_push(tsk, loginuid, sessionid, buf);
207 mutex_unlock(&buf->mutex); 224 mutex_unlock(&buf->mutex);
208 225
209 tty_audit_buf_put(buf); 226 tty_audit_buf_put(buf);
227 return 0;
210} 228}
211 229
212/** 230/**
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);
541extern void tty_audit_fork(struct signal_struct *sig); 541extern void tty_audit_fork(struct signal_struct *sig);
542extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); 542extern void tty_audit_tiocsti(struct tty_struct *tty, char ch);
543extern void tty_audit_push(struct tty_struct *tty); 543extern void tty_audit_push(struct tty_struct *tty);
544extern void tty_audit_push_task(struct task_struct *tsk, 544extern 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
547static inline void tty_audit_add_data(struct tty_struct *tty, 547static 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)
560static inline void tty_audit_push(struct tty_struct *tty) 560static inline void tty_audit_push(struct tty_struct *tty)
561{ 561{
562} 562}
563static inline void tty_audit_push_task(struct task_struct *tsk, 563static 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
diff --git a/kernel/audit.c b/kernel/audit.c
index a300931fc45f..8429afea37bf 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -467,23 +467,16 @@ static int audit_prepare_user_tty(pid_t pid, uid_t loginuid, u32 sessionid)
467 struct task_struct *tsk; 467 struct task_struct *tsk;
468 int err; 468 int err;
469 469
470 read_lock(&tasklist_lock); 470 rcu_read_lock();
471 tsk = find_task_by_vpid(pid); 471 tsk = find_task_by_vpid(pid);
472 err = -ESRCH; 472 if (!tsk) {
473 if (!tsk) 473 rcu_read_unlock();
474 goto out; 474 return -ESRCH;
475 err = 0; 475 }
476 476 get_task_struct(tsk);
477 spin_lock_irq(&tsk->sighand->siglock); 477 rcu_read_unlock();
478 if (!tsk->signal->audit_tty) 478 err = tty_audit_push_task(tsk, loginuid, sessionid);
479 err = -EPERM; 479 put_task_struct(tsk);
480 spin_unlock_irq(&tsk->sighand->siglock);
481 if (err)
482 goto out;
483
484 tty_audit_push_task(tsk, loginuid, sessionid);
485out:
486 read_unlock(&tasklist_lock);
487 return err; 480 return err;
488} 481}
489 482