diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-12-10 03:16:51 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-01-04 15:14:39 -0500 |
commit | f3298dc4f2277874d40cb4fc3a6e277317d6603b (patch) | |
tree | 8ba8f7e7a0597965b2f6c7106718a59cc164eab1 | |
parent | 4f6b434fee2402b3decdeae9d16eb648725ae426 (diff) |
sanitize audit_socketcall
* don't bother with allocations
* now that it can't fail, make it return void
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | include/linux/audit.h | 4 | ||||
-rw-r--r-- | kernel/auditsc.c | 66 | ||||
-rw-r--r-- | net/socket.c | 4 |
3 files changed, 41 insertions, 33 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 26c4f6f65a46..466a953d4bf6 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -446,7 +446,7 @@ extern void audit_log_task_context(struct audit_buffer *ab); | |||
446 | extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp); | 446 | extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp); |
447 | extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); | 447 | extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); |
448 | extern int audit_bprm(struct linux_binprm *bprm); | 448 | extern int audit_bprm(struct linux_binprm *bprm); |
449 | extern int audit_socketcall(int nargs, unsigned long *args); | 449 | extern void audit_socketcall(int nargs, unsigned long *args); |
450 | extern int audit_sockaddr(int len, void *addr); | 450 | extern int audit_sockaddr(int len, void *addr); |
451 | extern int __audit_fd_pair(int fd1, int fd2); | 451 | extern int __audit_fd_pair(int fd1, int fd2); |
452 | extern int audit_set_macxattr(const char *name); | 452 | extern int audit_set_macxattr(const char *name); |
@@ -549,7 +549,7 @@ extern int audit_signals; | |||
549 | #define audit_ipc_obj(i) ({ 0; }) | 549 | #define audit_ipc_obj(i) ({ 0; }) |
550 | #define audit_ipc_set_perm(q,u,g,m) ({ 0; }) | 550 | #define audit_ipc_set_perm(q,u,g,m) ({ 0; }) |
551 | #define audit_bprm(p) ({ 0; }) | 551 | #define audit_bprm(p) ({ 0; }) |
552 | #define audit_socketcall(n,a) ({ 0; }) | 552 | #define audit_socketcall(n,a) ((void)0) |
553 | #define audit_fd_pair(n,a) ({ 0; }) | 553 | #define audit_fd_pair(n,a) ({ 0; }) |
554 | #define audit_sockaddr(len, addr) ({ 0; }) | 554 | #define audit_sockaddr(len, addr) ({ 0; }) |
555 | #define audit_set_macxattr(n) do { ; } while (0) | 555 | #define audit_set_macxattr(n) do { ; } while (0) |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index c2e43ebb1b68..5cda66466e14 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -168,12 +168,6 @@ struct audit_aux_data_execve { | |||
168 | struct mm_struct *mm; | 168 | struct mm_struct *mm; |
169 | }; | 169 | }; |
170 | 170 | ||
171 | struct audit_aux_data_socketcall { | ||
172 | struct audit_aux_data d; | ||
173 | int nargs; | ||
174 | unsigned long args[0]; | ||
175 | }; | ||
176 | |||
177 | struct audit_aux_data_fd_pair { | 171 | struct audit_aux_data_fd_pair { |
178 | struct audit_aux_data d; | 172 | struct audit_aux_data d; |
179 | int fd[2]; | 173 | int fd[2]; |
@@ -247,6 +241,14 @@ struct audit_context { | |||
247 | struct audit_tree_refs *trees, *first_trees; | 241 | struct audit_tree_refs *trees, *first_trees; |
248 | int tree_count; | 242 | int tree_count; |
249 | 243 | ||
244 | int type; | ||
245 | union { | ||
246 | struct { | ||
247 | int nargs; | ||
248 | long args[6]; | ||
249 | } socketcall; | ||
250 | }; | ||
251 | |||
250 | #if AUDIT_DEBUG | 252 | #if AUDIT_DEBUG |
251 | int put_count; | 253 | int put_count; |
252 | int ino_count; | 254 | int ino_count; |
@@ -1226,6 +1228,27 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) | |||
1226 | audit_log_format(ab, " cap_fe=%d cap_fver=%x", name->fcap.fE, name->fcap_ver); | 1228 | audit_log_format(ab, " cap_fe=%d cap_fver=%x", name->fcap.fE, name->fcap_ver); |
1227 | } | 1229 | } |
1228 | 1230 | ||
1231 | static void show_special(struct audit_context *context) | ||
1232 | { | ||
1233 | struct audit_buffer *ab; | ||
1234 | int i; | ||
1235 | |||
1236 | ab = audit_log_start(context, GFP_KERNEL, context->type); | ||
1237 | if (!ab) | ||
1238 | return; | ||
1239 | |||
1240 | switch (context->type) { | ||
1241 | case AUDIT_SOCKETCALL: { | ||
1242 | int nargs = context->socketcall.nargs; | ||
1243 | audit_log_format(ab, "nargs=%d", nargs); | ||
1244 | for (i = 0; i < nargs; i++) | ||
1245 | audit_log_format(ab, " a%d=%lx", i, | ||
1246 | context->socketcall.args[i]); | ||
1247 | break; } | ||
1248 | } | ||
1249 | audit_log_end(ab); | ||
1250 | } | ||
1251 | |||
1229 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) | 1252 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) |
1230 | { | 1253 | { |
1231 | const struct cred *cred; | 1254 | const struct cred *cred; |
@@ -1372,13 +1395,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1372 | audit_log_execve_info(context, &ab, axi); | 1395 | audit_log_execve_info(context, &ab, axi); |
1373 | break; } | 1396 | break; } |
1374 | 1397 | ||
1375 | case AUDIT_SOCKETCALL: { | ||
1376 | struct audit_aux_data_socketcall *axs = (void *)aux; | ||
1377 | audit_log_format(ab, "nargs=%d", axs->nargs); | ||
1378 | for (i=0; i<axs->nargs; i++) | ||
1379 | audit_log_format(ab, " a%d=%lx", i, axs->args[i]); | ||
1380 | break; } | ||
1381 | |||
1382 | case AUDIT_FD_PAIR: { | 1398 | case AUDIT_FD_PAIR: { |
1383 | struct audit_aux_data_fd_pair *axs = (void *)aux; | 1399 | struct audit_aux_data_fd_pair *axs = (void *)aux; |
1384 | audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); | 1400 | audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); |
@@ -1410,6 +1426,9 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1410 | audit_log_end(ab); | 1426 | audit_log_end(ab); |
1411 | } | 1427 | } |
1412 | 1428 | ||
1429 | if (context->type) | ||
1430 | show_special(context); | ||
1431 | |||
1413 | if (context->sockaddr_len) { | 1432 | if (context->sockaddr_len) { |
1414 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_SOCKADDR); | 1433 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_SOCKADDR); |
1415 | if (ab) { | 1434 | if (ab) { |
@@ -1689,6 +1708,7 @@ void audit_syscall_exit(int valid, long return_code) | |||
1689 | context->target_pid = 0; | 1708 | context->target_pid = 0; |
1690 | context->target_sid = 0; | 1709 | context->target_sid = 0; |
1691 | context->sockaddr_len = 0; | 1710 | context->sockaddr_len = 0; |
1711 | context->type = 0; | ||
1692 | kfree(context->filterkey); | 1712 | kfree(context->filterkey); |
1693 | context->filterkey = NULL; | 1713 | context->filterkey = NULL; |
1694 | tsk->audit_context = context; | 1714 | tsk->audit_context = context; |
@@ -2406,27 +2426,17 @@ int audit_bprm(struct linux_binprm *bprm) | |||
2406 | * @nargs: number of args | 2426 | * @nargs: number of args |
2407 | * @args: args array | 2427 | * @args: args array |
2408 | * | 2428 | * |
2409 | * Returns 0 for success or NULL context or < 0 on error. | ||
2410 | */ | 2429 | */ |
2411 | int audit_socketcall(int nargs, unsigned long *args) | 2430 | void audit_socketcall(int nargs, unsigned long *args) |
2412 | { | 2431 | { |
2413 | struct audit_aux_data_socketcall *ax; | ||
2414 | struct audit_context *context = current->audit_context; | 2432 | struct audit_context *context = current->audit_context; |
2415 | 2433 | ||
2416 | if (likely(!context || context->dummy)) | 2434 | if (likely(!context || context->dummy)) |
2417 | return 0; | 2435 | return; |
2418 | |||
2419 | ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL); | ||
2420 | if (!ax) | ||
2421 | return -ENOMEM; | ||
2422 | |||
2423 | ax->nargs = nargs; | ||
2424 | memcpy(ax->args, args, nargs * sizeof(unsigned long)); | ||
2425 | 2436 | ||
2426 | ax->d.type = AUDIT_SOCKETCALL; | 2437 | context->type = AUDIT_SOCKETCALL; |
2427 | ax->d.next = context->aux; | 2438 | context->socketcall.nargs = nargs; |
2428 | context->aux = (void *)ax; | 2439 | memcpy(context->socketcall.args, args, nargs * sizeof(unsigned long)); |
2429 | return 0; | ||
2430 | } | 2440 | } |
2431 | 2441 | ||
2432 | /** | 2442 | /** |
diff --git a/net/socket.c b/net/socket.c index 2c730fc718ab..b41a92093e40 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -2065,9 +2065,7 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args) | |||
2065 | if (copy_from_user(a, args, nargs[call])) | 2065 | if (copy_from_user(a, args, nargs[call])) |
2066 | return -EFAULT; | 2066 | return -EFAULT; |
2067 | 2067 | ||
2068 | err = audit_socketcall(nargs[call] / sizeof(unsigned long), a); | 2068 | audit_socketcall(nargs[call] / sizeof(unsigned long), a); |
2069 | if (err) | ||
2070 | return err; | ||
2071 | 2069 | ||
2072 | a0 = a[0]; | 2070 | a0 = a[0]; |
2073 | a1 = a[1]; | 2071 | a1 = a[1]; |