diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2008-12-09 19:50:34 -0500 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-01-04 15:14:39 -0500 |
| commit | 4f6b434fee2402b3decdeae9d16eb648725ae426 (patch) | |
| tree | 2b82a9d220509e2fe42c365de5083eb8032880e4 /kernel | |
| parent | 7d3b56ba37a95f1f370f50258ed3954c304c524b (diff) | |
don't reallocate buffer in every audit_sockaddr()
No need to do that more than once per process lifetime; allocating/freeing
on each sendto/accept/etc. is bloody pointless.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/auditsc.c | 46 |
1 files changed, 22 insertions, 24 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 4819f3711973..c2e43ebb1b68 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -174,12 +174,6 @@ struct audit_aux_data_socketcall { | |||
| 174 | unsigned long args[0]; | 174 | unsigned long args[0]; |
| 175 | }; | 175 | }; |
| 176 | 176 | ||
| 177 | struct audit_aux_data_sockaddr { | ||
| 178 | struct audit_aux_data d; | ||
| 179 | int len; | ||
| 180 | char a[0]; | ||
| 181 | }; | ||
| 182 | |||
| 183 | struct audit_aux_data_fd_pair { | 177 | struct audit_aux_data_fd_pair { |
| 184 | struct audit_aux_data d; | 178 | struct audit_aux_data d; |
| 185 | int fd[2]; | 179 | int fd[2]; |
| @@ -234,7 +228,8 @@ struct audit_context { | |||
| 234 | struct audit_context *previous; /* For nested syscalls */ | 228 | struct audit_context *previous; /* For nested syscalls */ |
| 235 | struct audit_aux_data *aux; | 229 | struct audit_aux_data *aux; |
| 236 | struct audit_aux_data *aux_pids; | 230 | struct audit_aux_data *aux_pids; |
| 237 | 231 | struct sockaddr_storage *sockaddr; | |
| 232 | size_t sockaddr_len; | ||
| 238 | /* Save things to print about task_struct */ | 233 | /* Save things to print about task_struct */ |
| 239 | pid_t pid, ppid; | 234 | pid_t pid, ppid; |
| 240 | uid_t uid, euid, suid, fsuid; | 235 | uid_t uid, euid, suid, fsuid; |
| @@ -921,6 +916,7 @@ static inline void audit_free_context(struct audit_context *context) | |||
| 921 | free_tree_refs(context); | 916 | free_tree_refs(context); |
| 922 | audit_free_aux(context); | 917 | audit_free_aux(context); |
| 923 | kfree(context->filterkey); | 918 | kfree(context->filterkey); |
| 919 | kfree(context->sockaddr); | ||
| 924 | kfree(context); | 920 | kfree(context); |
| 925 | context = previous; | 921 | context = previous; |
| 926 | } while (context); | 922 | } while (context); |
| @@ -1383,13 +1379,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
| 1383 | audit_log_format(ab, " a%d=%lx", i, axs->args[i]); | 1379 | audit_log_format(ab, " a%d=%lx", i, axs->args[i]); |
| 1384 | break; } | 1380 | break; } |
| 1385 | 1381 | ||
| 1386 | case AUDIT_SOCKADDR: { | ||
| 1387 | struct audit_aux_data_sockaddr *axs = (void *)aux; | ||
| 1388 | |||
| 1389 | audit_log_format(ab, "saddr="); | ||
| 1390 | audit_log_n_hex(ab, axs->a, axs->len); | ||
| 1391 | break; } | ||
| 1392 | |||
| 1393 | case AUDIT_FD_PAIR: { | 1382 | case AUDIT_FD_PAIR: { |
| 1394 | struct audit_aux_data_fd_pair *axs = (void *)aux; | 1383 | struct audit_aux_data_fd_pair *axs = (void *)aux; |
| 1395 | audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); | 1384 | audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); |
| @@ -1421,6 +1410,16 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
| 1421 | audit_log_end(ab); | 1410 | audit_log_end(ab); |
| 1422 | } | 1411 | } |
| 1423 | 1412 | ||
| 1413 | if (context->sockaddr_len) { | ||
| 1414 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_SOCKADDR); | ||
| 1415 | if (ab) { | ||
| 1416 | audit_log_format(ab, "saddr="); | ||
| 1417 | audit_log_n_hex(ab, (void *)context->sockaddr, | ||
| 1418 | context->sockaddr_len); | ||
| 1419 | audit_log_end(ab); | ||
| 1420 | } | ||
| 1421 | } | ||
| 1422 | |||
| 1424 | for (aux = context->aux_pids; aux; aux = aux->next) { | 1423 | for (aux = context->aux_pids; aux; aux = aux->next) { |
| 1425 | struct audit_aux_data_pids *axs = (void *)aux; | 1424 | struct audit_aux_data_pids *axs = (void *)aux; |
| 1426 | 1425 | ||
| @@ -1689,6 +1688,7 @@ void audit_syscall_exit(int valid, long return_code) | |||
| 1689 | context->aux_pids = NULL; | 1688 | context->aux_pids = NULL; |
| 1690 | context->target_pid = 0; | 1689 | context->target_pid = 0; |
| 1691 | context->target_sid = 0; | 1690 | context->target_sid = 0; |
| 1691 | context->sockaddr_len = 0; | ||
| 1692 | kfree(context->filterkey); | 1692 | kfree(context->filterkey); |
| 1693 | context->filterkey = NULL; | 1693 | context->filterkey = NULL; |
| 1694 | tsk->audit_context = context; | 1694 | tsk->audit_context = context; |
| @@ -2468,22 +2468,20 @@ int __audit_fd_pair(int fd1, int fd2) | |||
| 2468 | */ | 2468 | */ |
| 2469 | int audit_sockaddr(int len, void *a) | 2469 | int audit_sockaddr(int len, void *a) |
| 2470 | { | 2470 | { |
| 2471 | struct audit_aux_data_sockaddr *ax; | ||
| 2472 | struct audit_context *context = current->audit_context; | 2471 | struct audit_context *context = current->audit_context; |
| 2473 | 2472 | ||
| 2474 | if (likely(!context || context->dummy)) | 2473 | if (likely(!context || context->dummy)) |
| 2475 | return 0; | 2474 | return 0; |
| 2476 | 2475 | ||
| 2477 | ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL); | 2476 | if (!context->sockaddr) { |
| 2478 | if (!ax) | 2477 | void *p = kmalloc(sizeof(struct sockaddr_storage), GFP_KERNEL); |
| 2479 | return -ENOMEM; | 2478 | if (!p) |
| 2480 | 2479 | return -ENOMEM; | |
| 2481 | ax->len = len; | 2480 | context->sockaddr = p; |
| 2482 | memcpy(ax->a, a, len); | 2481 | } |
| 2483 | 2482 | ||
| 2484 | ax->d.type = AUDIT_SOCKADDR; | 2483 | context->sockaddr_len = len; |
| 2485 | ax->d.next = context->aux; | 2484 | memcpy(context->sockaddr, a, len); |
| 2486 | context->aux = (void *)ax; | ||
| 2487 | return 0; | 2485 | return 0; |
| 2488 | } | 2486 | } |
| 2489 | 2487 | ||
