aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/n_tty.c
diff options
context:
space:
mode:
authorMiloslav Trmac <mitr@redhat.com>2007-07-16 02:40:56 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 12:05:47 -0400
commit522ed7767e800cff6c650ec64b0ee0677303119c (patch)
treef65ecb29f2cf885018d3557f840de3ef4be6ec64 /drivers/char/n_tty.c
parent4f27c00bf80f122513d3a5be16ed851573164534 (diff)
Audit: add TTY input auditing
Add TTY input auditing, used to audit system administrator's actions. This is required by various security standards such as DCID 6/3 and PCI to provide non-repudiation of administrator's actions and to allow a review of past actions if the administrator seems to overstep their duties or if the system becomes misconfigured for unknown reasons. These requirements do not make it necessary to audit TTY output as well. Compared to an user-space keylogger, this approach records TTY input using the audit subsystem, correlated with other audit events, and it is completely transparent to the user-space application (e.g. the console ioctls still work). TTY input auditing works on a higher level than auditing all system calls within the session, which would produce an overwhelming amount of mostly useless audit events. Add an "audit_tty" attribute, inherited across fork (). Data read from TTYs by process with the attribute is sent to the audit subsystem by the kernel. The audit netlink interface is extended to allow modifying the audit_tty attribute, and to allow sending explanatory audit events from user-space (for example, a shell might send an event containing the final command, after the interactive command-line editing and history expansion is performed, which might be difficult to decipher from the TTY input alone). Because the "audit_tty" attribute is inherited across fork (), it would be set e.g. for sshd restarted within an audited session. To prevent this, the audit_tty attribute is cleared when a process with no open TTY file descriptors (e.g. after daemon startup) opens a TTY. See https://www.redhat.com/archives/linux-audit/2007-June/msg00000.html for a more detailed rationale document for an older version of this patch. [akpm@linux-foundation.org: build fix] Signed-off-by: Miloslav Trmac <mitr@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: Paul Fulghum <paulkf@microgate.com> Cc: Casey Schaufler <casey@schaufler-ca.com> Cc: Steve Grubb <sgrubb@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/n_tty.c')
-rw-r--r--drivers/char/n_tty.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 371631f4bfb9..038056911934 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -45,6 +45,8 @@
45#include <linux/slab.h> 45#include <linux/slab.h>
46#include <linux/poll.h> 46#include <linux/poll.h>
47#include <linux/bitops.h> 47#include <linux/bitops.h>
48#include <linux/audit.h>
49#include <linux/file.h>
48 50
49#include <asm/uaccess.h> 51#include <asm/uaccess.h>
50#include <asm/system.h> 52#include <asm/system.h>
@@ -78,6 +80,13 @@ static inline void free_buf(unsigned char *buf)
78 free_page((unsigned long) buf); 80 free_page((unsigned long) buf);
79} 81}
80 82
83static inline int tty_put_user(struct tty_struct *tty, unsigned char x,
84 unsigned char __user *ptr)
85{
86 tty_audit_add_data(tty, &x, 1);
87 return put_user(x, ptr);
88}
89
81/** 90/**
82 * n_tty_set__room - receive space 91 * n_tty_set__room - receive space
83 * @tty: terminal 92 * @tty: terminal
@@ -1153,6 +1162,7 @@ static int copy_from_read_buf(struct tty_struct *tty,
1153 if (n) { 1162 if (n) {
1154 retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n); 1163 retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n);
1155 n -= retval; 1164 n -= retval;
1165 tty_audit_add_data(tty, &tty->read_buf[tty->read_tail], n);
1156 spin_lock_irqsave(&tty->read_lock, flags); 1166 spin_lock_irqsave(&tty->read_lock, flags);
1157 tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); 1167 tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1);
1158 tty->read_cnt -= n; 1168 tty->read_cnt -= n;
@@ -1279,7 +1289,7 @@ do_it_again:
1279 break; 1289 break;
1280 cs = tty->link->ctrl_status; 1290 cs = tty->link->ctrl_status;
1281 tty->link->ctrl_status = 0; 1291 tty->link->ctrl_status = 0;
1282 if (put_user(cs, b++)) { 1292 if (tty_put_user(tty, cs, b++)) {
1283 retval = -EFAULT; 1293 retval = -EFAULT;
1284 b--; 1294 b--;
1285 break; 1295 break;
@@ -1321,7 +1331,7 @@ do_it_again:
1321 1331
1322 /* Deal with packet mode. */ 1332 /* Deal with packet mode. */
1323 if (tty->packet && b == buf) { 1333 if (tty->packet && b == buf) {
1324 if (put_user(TIOCPKT_DATA, b++)) { 1334 if (tty_put_user(tty, TIOCPKT_DATA, b++)) {
1325 retval = -EFAULT; 1335 retval = -EFAULT;
1326 b--; 1336 b--;
1327 break; 1337 break;
@@ -1352,15 +1362,17 @@ do_it_again:
1352 spin_unlock_irqrestore(&tty->read_lock, flags); 1362 spin_unlock_irqrestore(&tty->read_lock, flags);
1353 1363
1354 if (!eol || (c != __DISABLED_CHAR)) { 1364 if (!eol || (c != __DISABLED_CHAR)) {
1355 if (put_user(c, b++)) { 1365 if (tty_put_user(tty, c, b++)) {
1356 retval = -EFAULT; 1366 retval = -EFAULT;
1357 b--; 1367 b--;
1358 break; 1368 break;
1359 } 1369 }
1360 nr--; 1370 nr--;
1361 } 1371 }
1362 if (eol) 1372 if (eol) {
1373 tty_audit_push(tty);
1363 break; 1374 break;
1375 }
1364 } 1376 }
1365 if (retval) 1377 if (retval)
1366 break; 1378 break;