diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2006-04-26 14:04:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2006-06-20 05:25:21 -0400 |
commit | 473ae30bc7b1dda5c5791c773f95e9424ddfead9 (patch) | |
tree | 541f6f20b9131fcfb650ca491e291d3c6b148a1b /kernel | |
parent | 9044e6bca5a4a575d3c068dfccb5651a2d6a13bc (diff) |
[PATCH] execve argument logging
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/audit.c | 8 | ||||
-rw-r--r-- | kernel/auditsc.c | 51 |
2 files changed, 56 insertions, 3 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index bf74bf02aa4b..d09f131b111a 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -1026,18 +1026,20 @@ void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, | |||
1026 | * or a space. Unescaped strings will start and end with a double quote mark. | 1026 | * or a space. Unescaped strings will start and end with a double quote mark. |
1027 | * Strings that are escaped are printed in hex (2 digits per char). | 1027 | * Strings that are escaped are printed in hex (2 digits per char). |
1028 | */ | 1028 | */ |
1029 | void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) | 1029 | const char *audit_log_untrustedstring(struct audit_buffer *ab, const char *string) |
1030 | { | 1030 | { |
1031 | const unsigned char *p = string; | 1031 | const unsigned char *p = string; |
1032 | size_t len = strlen(string); | ||
1032 | 1033 | ||
1033 | while (*p) { | 1034 | while (*p) { |
1034 | if (*p == '"' || *p < 0x21 || *p > 0x7f) { | 1035 | if (*p == '"' || *p < 0x21 || *p > 0x7f) { |
1035 | audit_log_hex(ab, string, strlen(string)); | 1036 | audit_log_hex(ab, string, len); |
1036 | return; | 1037 | return string + len + 1; |
1037 | } | 1038 | } |
1038 | p++; | 1039 | p++; |
1039 | } | 1040 | } |
1040 | audit_log_format(ab, "\"%s\"", string); | 1041 | audit_log_format(ab, "\"%s\"", string); |
1042 | return p + 1; | ||
1041 | } | 1043 | } |
1042 | 1044 | ||
1043 | /* This is a helper-function to print the escaped d_path */ | 1045 | /* This is a helper-function to print the escaped d_path */ |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 1c03a4ed1b27..114f921979ec 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <linux/list.h> | 59 | #include <linux/list.h> |
60 | #include <linux/tty.h> | 60 | #include <linux/tty.h> |
61 | #include <linux/selinux.h> | 61 | #include <linux/selinux.h> |
62 | #include <linux/binfmts.h> | ||
62 | 63 | ||
63 | #include "audit.h" | 64 | #include "audit.h" |
64 | 65 | ||
@@ -110,6 +111,13 @@ struct audit_aux_data_ipcctl { | |||
110 | u32 osid; | 111 | u32 osid; |
111 | }; | 112 | }; |
112 | 113 | ||
114 | struct audit_aux_data_execve { | ||
115 | struct audit_aux_data d; | ||
116 | int argc; | ||
117 | int envc; | ||
118 | char mem[0]; | ||
119 | }; | ||
120 | |||
113 | struct audit_aux_data_socketcall { | 121 | struct audit_aux_data_socketcall { |
114 | struct audit_aux_data d; | 122 | struct audit_aux_data d; |
115 | int nargs; | 123 | int nargs; |
@@ -667,6 +675,16 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
667 | kfree(ctx); | 675 | kfree(ctx); |
668 | } | 676 | } |
669 | break; } | 677 | break; } |
678 | case AUDIT_EXECVE: { | ||
679 | struct audit_aux_data_execve *axi = (void *)aux; | ||
680 | int i; | ||
681 | const char *p; | ||
682 | for (i = 0, p = axi->mem; i < axi->argc; i++) { | ||
683 | audit_log_format(ab, "a%d=", i); | ||
684 | p = audit_log_untrustedstring(ab, p); | ||
685 | audit_log_format(ab, "\n"); | ||
686 | } | ||
687 | break; } | ||
670 | 688 | ||
671 | case AUDIT_SOCKETCALL: { | 689 | case AUDIT_SOCKETCALL: { |
672 | int i; | 690 | int i; |
@@ -1231,6 +1249,39 @@ int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, | |||
1231 | return 0; | 1249 | return 0; |
1232 | } | 1250 | } |
1233 | 1251 | ||
1252 | int audit_bprm(struct linux_binprm *bprm) | ||
1253 | { | ||
1254 | struct audit_aux_data_execve *ax; | ||
1255 | struct audit_context *context = current->audit_context; | ||
1256 | unsigned long p, next; | ||
1257 | void *to; | ||
1258 | |||
1259 | if (likely(!audit_enabled || !context)) | ||
1260 | return 0; | ||
1261 | |||
1262 | ax = kmalloc(sizeof(*ax) + PAGE_SIZE * MAX_ARG_PAGES - bprm->p, | ||
1263 | GFP_KERNEL); | ||
1264 | if (!ax) | ||
1265 | return -ENOMEM; | ||
1266 | |||
1267 | ax->argc = bprm->argc; | ||
1268 | ax->envc = bprm->envc; | ||
1269 | for (p = bprm->p, to = ax->mem; p < MAX_ARG_PAGES*PAGE_SIZE; p = next) { | ||
1270 | struct page *page = bprm->page[p / PAGE_SIZE]; | ||
1271 | void *kaddr = kmap(page); | ||
1272 | next = (p + PAGE_SIZE) & ~(PAGE_SIZE - 1); | ||
1273 | memcpy(to, kaddr + (p & (PAGE_SIZE - 1)), next - p); | ||
1274 | to += next - p; | ||
1275 | kunmap(page); | ||
1276 | } | ||
1277 | |||
1278 | ax->d.type = AUDIT_EXECVE; | ||
1279 | ax->d.next = context->aux; | ||
1280 | context->aux = (void *)ax; | ||
1281 | return 0; | ||
1282 | } | ||
1283 | |||
1284 | |||
1234 | /** | 1285 | /** |
1235 | * audit_socketcall - record audit data for sys_socketcall | 1286 | * audit_socketcall - record audit data for sys_socketcall |
1236 | * @nargs: number of args | 1287 | * @nargs: number of args |