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