Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Audit: Log TIOCSTI

AUDIT_TTY records currently log all data read by processes marked for
TTY input auditing, even if the data was "pushed back" using the TIOCSTI
ioctl, not typed by the user.

This patch records all TIOCSTI calls to disambiguate the input. It
generates one audit message per character pushed back; considering
TIOCSTI is used very rarely, this simple solution is probably good
enough. (The only program I could find that uses TIOCSTI is mailx/nail
in "header editing" mode, e.g. using the ~h escape. mailx is used very
rarely, and the escapes are used even rarer.)

Signed-Off-By: Miloslav Trmac <mitr@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: James Morris <jmorris@namei.org>

authored by

Al Viro and committed by
James Morris
1e641743 94d6a5f7

+66 -17
+61 -17
drivers/char/tty_audit.c
··· 67 67 tty_audit_buf_free(buf); 68 68 } 69 69 70 + static void tty_audit_log(const char *description, struct task_struct *tsk, 71 + uid_t loginuid, unsigned sessionid, int major, 72 + int minor, unsigned char *data, size_t size) 73 + { 74 + struct audit_buffer *ab; 75 + 76 + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY); 77 + if (ab) { 78 + char name[sizeof(tsk->comm)]; 79 + uid_t uid = task_uid(tsk); 80 + 81 + audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u " 82 + "major=%d minor=%d comm=", description, 83 + tsk->pid, uid, loginuid, sessionid, 84 + major, minor); 85 + get_task_comm(name, tsk); 86 + audit_log_untrustedstring(ab, name); 87 + audit_log_format(ab, " data="); 88 + audit_log_n_hex(ab, data, size); 89 + audit_log_end(ab); 90 + } 91 + } 92 + 70 93 /** 71 94 * tty_audit_buf_push - Push buffered data out 72 95 * ··· 100 77 unsigned int sessionid, 101 78 struct tty_audit_buf *buf) 102 79 { 103 - struct audit_buffer *ab; 104 - 105 80 if (buf->valid == 0) 106 81 return; 107 82 if (audit_enabled == 0) 108 83 return; 109 - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY); 110 - if (ab) { 111 - char name[sizeof(tsk->comm)]; 112 - uid_t uid = task_uid(tsk); 113 - 114 - audit_log_format(ab, "tty pid=%u uid=%u auid=%u ses=%u " 115 - "major=%d minor=%d comm=", 116 - tsk->pid, uid, loginuid, sessionid, 117 - buf->major, buf->minor); 118 - get_task_comm(name, tsk); 119 - audit_log_untrustedstring(ab, name); 120 - audit_log_format(ab, " data="); 121 - audit_log_n_hex(ab, buf->data, buf->valid); 122 - audit_log_end(ab); 123 - } 84 + tty_audit_log("tty", tsk, loginuid, sessionid, buf->major, buf->minor, 85 + buf->data, buf->valid); 124 86 buf->valid = 0; 125 87 } 126 88 ··· 157 149 sig->audit_tty = current->signal->audit_tty; 158 150 spin_unlock_irq(&current->sighand->siglock); 159 151 sig->tty_audit_buf = NULL; 152 + } 153 + 154 + /** 155 + * tty_audit_tiocsti - Log TIOCSTI 156 + */ 157 + void tty_audit_tiocsti(struct tty_struct *tty, char ch) 158 + { 159 + struct tty_audit_buf *buf; 160 + int major, minor, should_audit; 161 + 162 + spin_lock_irq(&current->sighand->siglock); 163 + should_audit = current->signal->audit_tty; 164 + buf = current->signal->tty_audit_buf; 165 + if (buf) 166 + atomic_inc(&buf->count); 167 + spin_unlock_irq(&current->sighand->siglock); 168 + 169 + major = tty->driver->major; 170 + minor = tty->driver->minor_start + tty->index; 171 + if (buf) { 172 + mutex_lock(&buf->mutex); 173 + if (buf->major == major && buf->minor == minor) 174 + tty_audit_buf_push_current(buf); 175 + mutex_unlock(&buf->mutex); 176 + tty_audit_buf_put(buf); 177 + } 178 + 179 + if (should_audit && audit_enabled) { 180 + uid_t auid; 181 + unsigned int sessionid; 182 + 183 + auid = audit_get_loginuid(current); 184 + sessionid = audit_get_sessionid(current); 185 + tty_audit_log("ioctl=TIOCSTI", current, auid, sessionid, major, 186 + minor, &ch, 1); 187 + } 160 188 } 161 189 162 190 /**
+1
drivers/char/tty_io.c
··· 2018 2018 return -EPERM; 2019 2019 if (get_user(ch, p)) 2020 2020 return -EFAULT; 2021 + tty_audit_tiocsti(tty, ch); 2021 2022 ld = tty_ldisc_ref_wait(tty); 2022 2023 ld->ops->receive_buf(tty, &ch, &mbz, 1); 2023 2024 tty_ldisc_deref(ld);
+4
include/linux/tty.h
··· 442 442 size_t size); 443 443 extern void tty_audit_exit(void); 444 444 extern void tty_audit_fork(struct signal_struct *sig); 445 + extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); 445 446 extern void tty_audit_push(struct tty_struct *tty); 446 447 extern void tty_audit_push_task(struct task_struct *tsk, 447 448 uid_t loginuid, u32 sessionid); 448 449 #else 449 450 static inline void tty_audit_add_data(struct tty_struct *tty, 450 451 unsigned char *data, size_t size) 452 + { 453 + } 454 + static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch) 451 455 { 452 456 } 453 457 static inline void tty_audit_exit(void)