diff options
author | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-05-17 12:08:48 +0100 |
---|---|---|
committer | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-05-17 12:08:48 +0100 |
commit | 3ec3b2fba526ead2fa3f3d7c91924f39a0733749 (patch) | |
tree | 12b9b3de4e0d5bb3c977ea3ef534ba4f7e556cb9 /kernel/auditsc.c | |
parent | 69887ac1dcb79dfc773dabac2dd081fa6d6e2573 (diff) | |
download | lwn-3ec3b2fba526ead2fa3f3d7c91924f39a0733749.tar.gz lwn-3ec3b2fba526ead2fa3f3d7c91924f39a0733749.zip |
AUDIT: Capture sys_socketcall arguments and sockaddrs
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 773d28a3f701..818778d5b6ad 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -34,7 +34,7 @@ #include <asm/types.h> #include <linux/mm.h> #include <linux/module.h> - +#include <linux/socket.h> #include <linux/audit.h> #include <linux/personality.h> #include <linux/time.h> @@ -112,6 +112,18 @@ struct audit_aux_data_ipcctl { mode_t mode; }; +struct audit_aux_data_socketcall { + struct audit_aux_data d; + int nargs; + unsigned long args[0]; +}; + +struct audit_aux_data_sockaddr { + struct audit_aux_data d; + int len; + char a[0]; +}; + /* The per-task audit context. */ struct audit_context { @@ -694,7 +706,22 @@ static void audit_log_exit(struct audit_context *context) audit_log_format(ab, " qbytes=%lx iuid=%d igid=%d mode=%x", axi->qbytes, axi->uid, axi->gid, axi->mode); - } + break; } + + case AUDIT_SOCKETCALL: { + int i; + struct audit_aux_data_socketcall *axs = (void *)aux; + audit_log_format(ab, "nargs=%d", axs->nargs); + for (i=0; i<axs->nargs; i++) + audit_log_format(ab, " a%d=%lx", i, axs->args[i]); + break; } + + case AUDIT_SOCKADDR: { + struct audit_aux_data_sockaddr *axs = (void *)aux; + + audit_log_format(ab, "saddr="); + audit_log_hex(ab, axs->a, axs->len); + break; } } audit_log_end(ab); @@ -1053,6 +1080,48 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) return 0; } +int audit_socketcall(int nargs, unsigned long *args) +{ + struct audit_aux_data_socketcall *ax; + struct audit_context *context = current->audit_context; + + if (likely(!context)) + return 0; + + ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL); + if (!ax) + return -ENOMEM; + + ax->nargs = nargs; + memcpy(ax->args, args, nargs * sizeof(unsigned long)); + + ax->d.type = AUDIT_SOCKETCALL; + ax->d.next = context->aux; + context->aux = (void *)ax; + return 0; +} + +int audit_sockaddr(int len, void *a) +{ + struct audit_aux_data_sockaddr *ax; + struct audit_context *context = current->audit_context; + + if (likely(!context)) + return 0; + + ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL); + if (!ax) + return -ENOMEM; + + ax->len = len; + memcpy(ax->a, a, len); + + ax->d.type = AUDIT_SOCKADDR; + ax->d.next = context->aux; + context->aux = (void *)ax; + return 0; +} + void audit_signal_info(int sig, struct task_struct *t) { extern pid_t audit_sig_pid; |