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 |
