diff options
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 66 |
1 files changed, 38 insertions, 28 deletions
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 | /** |