From 2532386f480eefbdd67b48be55fb4fb3e5a6081c Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 18 Apr 2008 10:09:25 -0400 Subject: Audit: collect sessionid in netlink messages Previously I added sessionid output to all audit messages where it was available but we still didn't know the sessionid of the sender of netlink messages. This patch adds that information to netlink messages so we can audit who sent netlink messages. Signed-off-by: Eric Paris Signed-off-by: Al Viro --- drivers/char/tty_audit.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c index 7722466e052..9739bbfc8f7 100644 --- a/drivers/char/tty_audit.c +++ b/drivers/char/tty_audit.c @@ -151,14 +151,9 @@ void tty_audit_fork(struct signal_struct *sig) /** * tty_audit_push_task - Flush task's pending audit data */ -void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid) +void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid) { struct tty_audit_buf *buf; - /* FIXME I think this is correct. Check against netlink once that is - * I really need to read this code more closely. But that's for - * another patch. - */ - unsigned int sessionid = audit_get_sessionid(tsk); spin_lock_irq(&tsk->sighand->siglock); buf = tsk->signal->tty_audit_buf; -- cgit v1.2.3-70-g09d2 From b556f8ad58c6e9f8f485c8cef7546e3fc82c382a Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 18 Apr 2008 10:12:59 -0400 Subject: Audit: standardize string audit interfaces This patch standardized the string auditing interfaces. No userspace changes will be visible and this is all just cleanup and consistancy work. We have the following string audit interfaces to use: void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len); void audit_log_n_string(struct audit_buffer *ab, const char *buf, size_t n); void audit_log_string(struct audit_buffer *ab, const char *buf); void audit_log_n_untrustedstring(struct audit_buffer *ab, const char *string, size_t n); void audit_log_untrustedstring(struct audit_buffer *ab, const char *string); This may be the first step to possibly fixing some of the issues that people have with the string output from the kernel audit system. But we still don't have an agreed upon solution to that problem. Signed-off-by: Eric Paris Signed-off-by: Al Viro --- drivers/char/tty_audit.c | 2 +- include/linux/audit.h | 22 ++++++++++++++-------- kernel/audit.c | 19 +++++++++---------- kernel/auditsc.c | 8 ++++---- security/selinux/avc.c | 2 +- 5 files changed, 29 insertions(+), 24 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c index 9739bbfc8f7..caeedd12d49 100644 --- a/drivers/char/tty_audit.c +++ b/drivers/char/tty_audit.c @@ -92,7 +92,7 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid, get_task_comm(name, tsk); audit_log_untrustedstring(ab, name); audit_log_format(ab, " data="); - audit_log_n_untrustedstring(ab, buf->valid, buf->data); + audit_log_n_untrustedstring(ab, buf->data, buf->valid); audit_log_end(ab); } buf->valid = 0; diff --git a/include/linux/audit.h b/include/linux/audit.h index 25f6ae30dd4..f938335af75 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -549,16 +549,20 @@ extern void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) __attribute__((format(printf,2,3))); extern void audit_log_end(struct audit_buffer *ab); -extern void audit_log_hex(struct audit_buffer *ab, - const unsigned char *buf, - size_t len); extern int audit_string_contains_control(const char *string, size_t len); +extern void audit_log_n_hex(struct audit_buffer *ab, + const unsigned char *buf, + size_t len); +extern void audit_log_n_string(struct audit_buffer *ab, + const char *buf, + size_t n); +#define audit_log_string(a,b) audit_log_n_string(a, b, strlen(b)); +extern void audit_log_n_untrustedstring(struct audit_buffer *ab, + const char *string, + size_t n); extern void audit_log_untrustedstring(struct audit_buffer *ab, const char *string); -extern void audit_log_n_untrustedstring(struct audit_buffer *ab, - size_t n, - const char *string); extern void audit_log_d_path(struct audit_buffer *ab, const char *prefix, struct path *path); @@ -578,9 +582,11 @@ extern int audit_enabled; #define audit_log_vformat(b,f,a) do { ; } while (0) #define audit_log_format(b,f,...) do { ; } while (0) #define audit_log_end(b) do { ; } while (0) -#define audit_log_hex(a,b,l) do { ; } while (0) -#define audit_log_untrustedstring(a,s) do { ; } while (0) +#define audit_log_n_hex(a,b,l) do { ; } while (0) +#define audit_log_n_string(a,c,l) do { ; } while (0) +#define audit_log_string(a,c) do { ; } while (0) #define audit_log_n_untrustedstring(a,n,s) do { ; } while (0) +#define audit_log_untrustedstring(a,s) do { ; } while (0) #define audit_log_d_path(b, p, d) do { ; } while (0) #define audit_enabled 0 #endif diff --git a/kernel/audit.c b/kernel/audit.c index 520583d8ca1..5b9ad3dda88 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -757,8 +757,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) audit_log_format(ab, " msg="); size = nlmsg_len(nlh); - audit_log_n_untrustedstring(ab, size, - data); + audit_log_n_untrustedstring(ab, data, size); } audit_set_pid(ab, pid); audit_log_end(ab); @@ -1293,7 +1292,7 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) * This function will take the passed buf and convert it into a string of * ascii hex digits. The new string is placed onto the skb. */ -void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, +void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len) { int i, avail, new_len; @@ -1329,8 +1328,8 @@ void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, * Format a string of no more than slen characters into the audit buffer, * enclosed in quote marks. */ -static void audit_log_n_string(struct audit_buffer *ab, size_t slen, - const char *string) +void audit_log_n_string(struct audit_buffer *ab, const char *string, + size_t slen) { int avail, new_len; unsigned char *ptr; @@ -1386,13 +1385,13 @@ int audit_string_contains_control(const char *string, size_t len) * The caller specifies the number of characters in the string to log, which may * or may not be the entire string. */ -void audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len, - const char *string) +void audit_log_n_untrustedstring(struct audit_buffer *ab, const char *string, + size_t len) { if (audit_string_contains_control(string, len)) - audit_log_hex(ab, string, len); + audit_log_n_hex(ab, string, len); else - audit_log_n_string(ab, len, string); + audit_log_n_string(ab, string, len); } /** @@ -1405,7 +1404,7 @@ void audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len, */ void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) { - audit_log_n_untrustedstring(ab, strlen(string), string); + audit_log_n_untrustedstring(ab, string, strlen(string)); } /* This is a helper-function to print the escaped d_path */ diff --git a/kernel/auditsc.c b/kernel/auditsc.c index d7249fcdc44..0072b1d8b25 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1095,7 +1095,7 @@ static int audit_log_single_execve_arg(struct audit_context *context, audit_log_format(*ab, "[%d]", i); audit_log_format(*ab, "="); if (has_cntl) - audit_log_hex(*ab, buf, to_send); + audit_log_n_hex(*ab, buf, to_send); else audit_log_format(*ab, "\"%s\"", buf); audit_log_format(*ab, "\n"); @@ -1307,7 +1307,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts struct audit_aux_data_sockaddr *axs = (void *)aux; audit_log_format(ab, "saddr="); - audit_log_hex(ab, axs->a, axs->len); + audit_log_n_hex(ab, axs->a, axs->len); break; } case AUDIT_FD_PAIR: { @@ -1371,8 +1371,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts default: /* log the name's directory component */ audit_log_format(ab, " name="); - audit_log_n_untrustedstring(ab, n->name_len, - n->name); + audit_log_n_untrustedstring(ab, n->name, + n->name_len); } } else audit_log_format(ab, " name=(null)"); diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 95a8ef4a507..114b4b4c97b 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -646,7 +646,7 @@ void avc_audit(u32 ssid, u32 tsid, if (*p) audit_log_untrustedstring(ab, p); else - audit_log_hex(ab, p, len); + audit_log_n_hex(ab, p, len); break; } } -- cgit v1.2.3-70-g09d2 From 41126226e186d92a45ed664e546abb5204588359 Mon Sep 17 00:00:00 2001 From: Miloslav Trmac Date: Fri, 18 Apr 2008 13:30:14 -0700 Subject: [patch 1/2] audit: let userspace fully control TTY input auditing Remove the code that automatically disables TTY input auditing in processes that open TTYs when they have no other TTY open; this heuristic was intended to automatically handle daemons, but it has false positives (e.g. with sshd) that make it impossible to control TTY input auditing from a PAM module. With this patch, TTY input auditing is controlled from user-space only. On the other hand, not even for daemons does it make sense to audit "input" from PTY masters; this data was produced by a program writing to the PTY slave, and does not represent data entered by the user. Signed-off-by: Miloslav Trmac Cc: Al Viro Cc: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: Al Viro --- drivers/char/tty_audit.c | 54 ++++-------------------------------------------- drivers/char/tty_io.c | 5 +---- include/linux/tty.h | 5 ----- 3 files changed, 5 insertions(+), 59 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c index caeedd12d49..6342b0534f4 100644 --- a/drivers/char/tty_audit.c +++ b/drivers/char/tty_audit.c @@ -233,6 +233,10 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, if (unlikely(size == 0)) return; + if (tty->driver->type == TTY_DRIVER_TYPE_PTY + && tty->driver->subtype == PTY_TYPE_MASTER) + return; + buf = tty_audit_buf_get(tty); if (!buf) return; @@ -295,53 +299,3 @@ void tty_audit_push(struct tty_struct *tty) tty_audit_buf_put(buf); } } - -/** - * tty_audit_opening - A TTY is being opened. - * - * As a special hack, tasks that close all their TTYs and open new ones - * are assumed to be system daemons (e.g. getty) and auditing is - * automatically disabled for them. - */ -void tty_audit_opening(void) -{ - int disable; - - disable = 1; - spin_lock_irq(¤t->sighand->siglock); - if (current->signal->audit_tty == 0) - disable = 0; - spin_unlock_irq(¤t->sighand->siglock); - if (!disable) - return; - - task_lock(current); - if (current->files) { - struct fdtable *fdt; - unsigned i; - - /* - * We don't take a ref to the file, so we must hold ->file_lock - * instead. - */ - spin_lock(¤t->files->file_lock); - fdt = files_fdtable(current->files); - for (i = 0; i < fdt->max_fds; i++) { - struct file *filp; - - filp = fcheck_files(current->files, i); - if (filp && is_tty(filp)) { - disable = 0; - break; - } - } - spin_unlock(¤t->files->file_lock); - } - task_unlock(current); - if (!disable) - return; - - spin_lock_irq(¤t->sighand->siglock); - current->signal->audit_tty = 0; - spin_unlock_irq(¤t->sighand->siglock); -} diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 4d3c7018f0c..afddccf1bb3 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2755,7 +2755,6 @@ got_driver: __proc_set_tty(current, tty); spin_unlock_irq(¤t->sighand->siglock); mutex_unlock(&tty_mutex); - tty_audit_opening(); return 0; } @@ -2818,10 +2817,8 @@ static int ptmx_open(struct inode *inode, struct file *filp) check_tty_count(tty, "tty_open"); retval = ptm_driver->open(tty, filp); - if (!retval) { - tty_audit_opening(); + if (!retval) return 0; - } out1: release_dev(filp); return retval; diff --git a/include/linux/tty.h b/include/linux/tty.h index 430624504ca..265831ccaa8 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -300,7 +300,6 @@ extern void tty_hangup(struct tty_struct * tty); extern void tty_vhangup(struct tty_struct * tty); extern void tty_unhangup(struct file *filp); extern int tty_hung_up_p(struct file * filp); -extern int is_tty(struct file *filp); extern void do_SAK(struct tty_struct *tty); extern void __do_SAK(struct tty_struct *tty); extern void disassociate_ctty(int priv); @@ -352,7 +351,6 @@ extern void tty_audit_exit(void); extern void tty_audit_fork(struct signal_struct *sig); extern void tty_audit_push(struct tty_struct *tty); extern void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid); -extern void tty_audit_opening(void); #else static inline void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, size_t size) @@ -370,9 +368,6 @@ static inline void tty_audit_push(struct tty_struct *tty) static inline void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid) { } -static inline void tty_audit_opening(void) -{ -} #endif /* tty_ioctl.c */ -- cgit v1.2.3-70-g09d2