*/
#include <linux/audit.h>
-#include <linux/file.h>
-#include <linux/fdtable.h>
+#include <linux/slab.h>
#include <linux/tty.h>
struct tty_audit_buf {
buf = kmalloc(sizeof(*buf), GFP_KERNEL);
if (!buf)
goto err;
- if (PAGE_SIZE != N_TTY_BUF_SIZE)
- buf->data = kmalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
- else
- buf->data = (unsigned char *)__get_free_page(GFP_KERNEL);
+ buf->data = kmalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
if (!buf->data)
goto err_buf;
atomic_set(&buf->count, 1);
static void tty_audit_buf_free(struct tty_audit_buf *buf)
{
WARN_ON(buf->valid != 0);
- if (PAGE_SIZE != N_TTY_BUF_SIZE)
- kfree(buf->data);
- else
- free_page((unsigned long)buf->data);
+ kfree(buf->data);
kfree(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;
}
spin_lock_irq(¤t->sighand->siglock);
sig->audit_tty = current->signal->audit_tty;
spin_unlock_irq(¤t->sighand->siglock);
- sig->tty_audit_buf = NULL;
+}
+
+/**
+ * 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(¤t->sighand->siglock);
+ should_audit = current->signal->audit_tty;
+ buf = current->signal->tty_audit_buf;
+ if (buf)
+ atomic_inc(&buf->count);
+ spin_unlock_irq(¤t->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);
+ }
}
/**