summaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAl Viro <viro@ZenIV.linux.org.uk>2008-12-09 09:23:33 +0000
committerJames Morris <jmorris@namei.org>2008-12-09 20:32:06 +1100
commit1e641743f055f075ed9a4edd75f1fb1e05669ddc (patch)
tree8016113a4965a344415e8bd6366f07c23eee7d5f /drivers/char
parent94d6a5f7341ebaff53d4e41cc81fab37f0d9fbed (diff)
downloadblackbird-op-linux-1e641743f055f075ed9a4edd75f1fb1e05669ddc.tar.gz
blackbird-op-linux-1e641743f055f075ed9a4edd75f1fb1e05669ddc.zip
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>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/tty_audit.c78
-rw-r--r--drivers/char/tty_io.c1
2 files changed, 62 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)
tty_audit_buf_free(buf);
}
-/**
- * tty_audit_buf_push - Push buffered data out
- *
- * Generate an audit message from the contents of @buf, which is owned by
- * @tsk with @loginuid. @buf->mutex must be locked.
- */
-static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
- unsigned int sessionid,
- struct tty_audit_buf *buf)
+static void tty_audit_log(const char *description, struct task_struct *tsk,
+ uid_t loginuid, unsigned sessionid, int major,
+ int minor, unsigned char *data, size_t size)
{
struct audit_buffer *ab;
- if (buf->valid == 0)
- return;
- if (audit_enabled == 0)
- return;
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY);
if (ab) {
char name[sizeof(tsk->comm)];
uid_t uid = task_uid(tsk);
- audit_log_format(ab, "tty pid=%u uid=%u auid=%u ses=%u "
- "major=%d minor=%d comm=",
+ audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u "
+ "major=%d minor=%d comm=", description,
tsk->pid, uid, loginuid, sessionid,
- buf->major, buf->minor);
+ major, minor);
get_task_comm(name, tsk);
audit_log_untrustedstring(ab, name);
audit_log_format(ab, " data=");
- audit_log_n_hex(ab, buf->data, buf->valid);
+ audit_log_n_hex(ab, data, size);
audit_log_end(ab);
}
+}
+
+/**
+ * tty_audit_buf_push - Push buffered data out
+ *
+ * Generate an audit message from the contents of @buf, which is owned by
+ * @tsk with @loginuid. @buf->mutex must be locked.
+ */
+static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
+ unsigned int sessionid,
+ struct tty_audit_buf *buf)
+{
+ if (buf->valid == 0)
+ return;
+ if (audit_enabled == 0)
+ return;
+ tty_audit_log("tty", tsk, loginuid, sessionid, buf->major, buf->minor,
+ buf->data, buf->valid);
buf->valid = 0;
}
@@ -152,6 +160,42 @@ void tty_audit_fork(struct signal_struct *sig)
}
/**
+ * tty_audit_tiocsti - Log TIOCSTI
+ */
+void tty_audit_tiocsti(struct tty_struct *tty, char ch)
+{
+ struct tty_audit_buf *buf;
+ int major, minor, should_audit;
+
+ spin_lock_irq(&current->sighand->siglock);
+ should_audit = current->signal->audit_tty;
+ buf = current->signal->tty_audit_buf;
+ if (buf)
+ atomic_inc(&buf->count);
+ spin_unlock_irq(&current->sighand->siglock);
+
+ major = tty->driver->major;
+ minor = tty->driver->minor_start + tty->index;
+ if (buf) {
+ mutex_lock(&buf->mutex);
+ if (buf->major == major && buf->minor == minor)
+ tty_audit_buf_push_current(buf);
+ mutex_unlock(&buf->mutex);
+ tty_audit_buf_put(buf);
+ }
+
+ if (should_audit && audit_enabled) {
+ uid_t auid;
+ unsigned int sessionid;
+
+ auid = audit_get_loginuid(current);
+ sessionid = audit_get_sessionid(current);
+ tty_audit_log("ioctl=TIOCSTI", current, auid, sessionid, major,
+ minor, &ch, 1);
+ }
+}
+
+/**
* tty_audit_push_task - Flush task's pending audit data
*/
void 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)
return -EPERM;
if (get_user(ch, p))
return -EFAULT;
+ tty_audit_tiocsti(tty, ch);
ld = tty_ldisc_ref_wait(tty);
ld->ops->receive_buf(tty, &ch, &mbz, 1);
tty_ldisc_deref(ld);
OpenPOWER on IntegriCloud