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 | |
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>
-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 | ||