aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/tty_audit.c78
-rw-r--r--drivers/char/tty_io.c1
-rw-r--r--include/linux/tty.h4
3 files changed, 66 insertions, 17 deletions
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c
index d961fa9612c4..34ab6d798f81 100644
--- a/drivers/char/tty_audit.c
+++ b/drivers/char/tty_audit.c
@@ -67,37 +67,45 @@ static void tty_audit_buf_put(struct tty_audit_buf *buf)
67 tty_audit_buf_free(buf); 67 tty_audit_buf_free(buf);
68} 68}
69 69
70/** 70static void tty_audit_log(const char *description, struct task_struct *tsk,
71 * tty_audit_buf_push - Push buffered data out 71 uid_t loginuid, unsigned sessionid, int major,
72 * 72 int minor, unsigned char *data, size_t size)
73 * Generate an audit message from the contents of @buf, which is owned by
74 * @tsk with @loginuid. @buf->mutex must be locked.
75 */
76static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
77 unsigned int sessionid,
78 struct tty_audit_buf *buf)
79{ 73{
80 struct audit_buffer *ab; 74 struct audit_buffer *ab;
81 75
82 if (buf->valid == 0)
83 return;
84 if (audit_enabled == 0)
85 return;
86 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY); 76 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY);
87 if (ab) { 77 if (ab) {
88 char name[sizeof(tsk->comm)]; 78 char name[sizeof(tsk->comm)];
89 uid_t uid = task_uid(tsk); 79 uid_t uid = task_uid(tsk);
90 80
91 audit_log_format(ab, "tty pid=%u uid=%u auid=%u ses=%u " 81 audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u "
92 "major=%d minor=%d comm=", 82 "major=%d minor=%d comm=", description,
93 tsk->pid, uid, loginuid, sessionid, 83 tsk->pid, uid, loginuid, sessionid,
94 buf->major, buf->minor); 84 major, minor);
95 get_task_comm(name, tsk); 85 get_task_comm(name, tsk);
96 audit_log_untrustedstring(ab, name); 86 audit_log_untrustedstring(ab, name);
97 audit_log_format(ab, " data="); 87 audit_log_format(ab, " data=");
98 audit_log_n_hex(ab, buf->data, buf->valid); 88 audit_log_n_hex(ab, data, size);
99 audit_log_end(ab); 89 audit_log_end(ab);
100 } 90 }
91}
92
93/**
94 * tty_audit_buf_push - Push buffered data out
95 *
96 * Generate an audit message from the contents of @buf, which is owned by
97 * @tsk with @loginuid. @buf->mutex must be locked.
98 */
99static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
100 unsigned int sessionid,
101 struct tty_audit_buf *buf)
102{
103 if (buf->valid == 0)
104 return;
105 if (audit_enabled == 0)
106 return;
107 tty_audit_log("tty", tsk, loginuid, sessionid, buf->major, buf->minor,
108 buf->data, buf->valid);
101 buf->valid = 0; 109 buf->valid = 0;
102} 110}
103 111
@@ -152,6 +160,42 @@ void tty_audit_fork(struct signal_struct *sig)
152} 160}
153 161
154/** 162/**
163 * tty_audit_tiocsti - Log TIOCSTI
164 */
165void tty_audit_tiocsti(struct tty_struct *tty, char ch)
166{
167 struct tty_audit_buf *buf;
168 int major, minor, should_audit;
169
170 spin_lock_irq(&current->sighand->siglock);
171 should_audit = current->signal->audit_tty;
172 buf = current->signal->tty_audit_buf;
173 if (buf)
174 atomic_inc(&buf->count);
175 spin_unlock_irq(&current->sighand->siglock);
176
177 major = tty->driver->major;
178 minor = tty->driver->minor_start + tty->index;
179 if (buf) {
180 mutex_lock(&buf->mutex);
181 if (buf->major == major && buf->minor == minor)
182 tty_audit_buf_push_current(buf);
183 mutex_unlock(&buf->mutex);
184 tty_audit_buf_put(buf);
185 }
186
187 if (should_audit && audit_enabled) {
188 uid_t auid;
189 unsigned int sessionid;
190
191 auid = audit_get_loginuid(current);
192 sessionid = audit_get_sessionid(current);
193 tty_audit_log("ioctl=TIOCSTI", current, auid, sessionid, major,
194 minor, &ch, 1);
195 }
196}
197
198/**
155 * tty_audit_push_task - Flush task's pending audit data 199 * tty_audit_push_task - Flush task's pending audit data
156 */ 200 */
157void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid) 201void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid)
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 1412a8d1e58d..db15f9ba7c0b 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2018,6 +2018,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
2018 return -EPERM; 2018 return -EPERM;
2019 if (get_user(ch, p)) 2019 if (get_user(ch, p))
2020 return -EFAULT; 2020 return -EFAULT;
2021 tty_audit_tiocsti(tty, ch);
2021 ld = tty_ldisc_ref_wait(tty); 2022 ld = tty_ldisc_ref_wait(tty);
2022 ld->ops->receive_buf(tty, &ch, &mbz, 1); 2023 ld->ops->receive_buf(tty, &ch, &mbz, 1);
2023 tty_ldisc_deref(ld); 2024 tty_ldisc_deref(ld);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 3b8121d4e36f..580700f20a1c 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -442,6 +442,7 @@ extern void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
442 size_t size); 442 size_t size);
443extern void tty_audit_exit(void); 443extern void tty_audit_exit(void);
444extern void tty_audit_fork(struct signal_struct *sig); 444extern void tty_audit_fork(struct signal_struct *sig);
445extern void tty_audit_tiocsti(struct tty_struct *tty, char ch);
445extern void tty_audit_push(struct tty_struct *tty); 446extern void tty_audit_push(struct tty_struct *tty);
446extern void tty_audit_push_task(struct task_struct *tsk, 447extern void tty_audit_push_task(struct task_struct *tsk,
447 uid_t loginuid, u32 sessionid); 448 uid_t loginuid, u32 sessionid);
@@ -450,6 +451,9 @@ static inline void tty_audit_add_data(struct tty_struct *tty,
450 unsigned char *data, size_t size) 451 unsigned char *data, size_t size)
451{ 452{
452} 453}
454static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch)
455{
456}
453static inline void tty_audit_exit(void) 457static inline void tty_audit_exit(void)
454{ 458{
455} 459}