diff options
-rw-r--r-- | include/linux/audit.h | 9 | ||||
-rw-r--r-- | ipc/shm.c | 4 | ||||
-rw-r--r-- | ipc/util.c | 9 | ||||
-rw-r--r-- | kernel/auditsc.c | 88 |
4 files changed, 45 insertions, 65 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 466a953d4bf6..f8578b9088e1 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -443,7 +443,7 @@ extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); | |||
443 | #define audit_get_loginuid(t) ((t)->loginuid) | 443 | #define audit_get_loginuid(t) ((t)->loginuid) |
444 | #define audit_get_sessionid(t) ((t)->sessionid) | 444 | #define audit_get_sessionid(t) ((t)->sessionid) |
445 | extern void audit_log_task_context(struct audit_buffer *ab); | 445 | extern void audit_log_task_context(struct audit_buffer *ab); |
446 | extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp); | 446 | extern void __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 void audit_socketcall(int nargs, unsigned long *args); | 449 | extern void audit_socketcall(int nargs, unsigned long *args); |
@@ -460,11 +460,10 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm, | |||
460 | const struct cred *old); | 460 | const struct cred *old); |
461 | extern int __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old); | 461 | extern int __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old); |
462 | 462 | ||
463 | static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp) | 463 | static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) |
464 | { | 464 | { |
465 | if (unlikely(!audit_dummy_context())) | 465 | if (unlikely(!audit_dummy_context())) |
466 | return __audit_ipc_obj(ipcp); | 466 | __audit_ipc_obj(ipcp); |
467 | return 0; | ||
468 | } | 467 | } |
469 | static inline int audit_fd_pair(int fd1, int fd2) | 468 | static inline int audit_fd_pair(int fd1, int fd2) |
470 | { | 469 | { |
@@ -546,7 +545,7 @@ extern int audit_signals; | |||
546 | #define audit_get_loginuid(t) (-1) | 545 | #define audit_get_loginuid(t) (-1) |
547 | #define audit_get_sessionid(t) (-1) | 546 | #define audit_get_sessionid(t) (-1) |
548 | #define audit_log_task_context(b) do { ; } while (0) | 547 | #define audit_log_task_context(b) do { ; } while (0) |
549 | #define audit_ipc_obj(i) ({ 0; }) | 548 | #define audit_ipc_obj(i) ((void)0) |
550 | #define audit_ipc_set_perm(q,u,g,m) ({ 0; }) | 549 | #define audit_ipc_set_perm(q,u,g,m) ({ 0; }) |
551 | #define audit_bprm(p) ({ 0; }) | 550 | #define audit_bprm(p) ({ 0; }) |
552 | #define audit_socketcall(n,a) ((void)0) | 551 | #define audit_socketcall(n,a) ((void)0) |
@@ -747,9 +747,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) | |||
747 | goto out; | 747 | goto out; |
748 | } | 748 | } |
749 | 749 | ||
750 | err = audit_ipc_obj(&(shp->shm_perm)); | 750 | audit_ipc_obj(&(shp->shm_perm)); |
751 | if (err) | ||
752 | goto out_unlock; | ||
753 | 751 | ||
754 | if (!capable(CAP_IPC_LOCK)) { | 752 | if (!capable(CAP_IPC_LOCK)) { |
755 | uid_t euid = current_euid(); | 753 | uid_t euid = current_euid(); |
diff --git a/ipc/util.c b/ipc/util.c index 5a1808c774a2..579552abd50a 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
@@ -624,10 +624,9 @@ void ipc_rcu_putref(void *ptr) | |||
624 | int ipcperms (struct kern_ipc_perm *ipcp, short flag) | 624 | int ipcperms (struct kern_ipc_perm *ipcp, short flag) |
625 | { /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */ | 625 | { /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */ |
626 | uid_t euid = current_euid(); | 626 | uid_t euid = current_euid(); |
627 | int requested_mode, granted_mode, err; | 627 | int requested_mode, granted_mode; |
628 | 628 | ||
629 | if (unlikely((err = audit_ipc_obj(ipcp)))) | 629 | audit_ipc_obj(ipcp); |
630 | return err; | ||
631 | requested_mode = (flag >> 6) | (flag >> 3) | flag; | 630 | requested_mode = (flag >> 6) | (flag >> 3) | flag; |
632 | granted_mode = ipcp->mode; | 631 | granted_mode = ipcp->mode; |
633 | if (euid == ipcp->cuid || | 632 | if (euid == ipcp->cuid || |
@@ -803,9 +802,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd, | |||
803 | goto out_up; | 802 | goto out_up; |
804 | } | 803 | } |
805 | 804 | ||
806 | err = audit_ipc_obj(ipcp); | 805 | audit_ipc_obj(ipcp); |
807 | if (err) | ||
808 | goto out_unlock; | ||
809 | 806 | ||
810 | if (cmd == IPC_SET) { | 807 | if (cmd == IPC_SET) { |
811 | err = audit_ipc_set_perm(extra_perm, perm->uid, | 808 | err = audit_ipc_set_perm(extra_perm, perm->uid, |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 5cda66466e14..73504313264f 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -247,6 +247,12 @@ struct audit_context { | |||
247 | int nargs; | 247 | int nargs; |
248 | long args[6]; | 248 | long args[6]; |
249 | } socketcall; | 249 | } socketcall; |
250 | struct { | ||
251 | uid_t uid; | ||
252 | gid_t gid; | ||
253 | mode_t mode; | ||
254 | u32 osid; | ||
255 | } ipc; | ||
250 | }; | 256 | }; |
251 | 257 | ||
252 | #if AUDIT_DEBUG | 258 | #if AUDIT_DEBUG |
@@ -605,19 +611,12 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
605 | } | 611 | } |
606 | } | 612 | } |
607 | /* Find ipc objects that match */ | 613 | /* Find ipc objects that match */ |
608 | if (ctx) { | 614 | if (!ctx || ctx->type != AUDIT_IPC) |
609 | struct audit_aux_data *aux; | 615 | break; |
610 | for (aux = ctx->aux; aux; | 616 | if (security_audit_rule_match(ctx->ipc.osid, |
611 | aux = aux->next) { | 617 | f->type, f->op, |
612 | if (aux->type == AUDIT_IPC) { | 618 | f->lsm_rule, ctx)) |
613 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 619 | ++result; |
614 | if (security_audit_rule_match(axi->osid, f->type, f->op, f->lsm_rule, ctx)) { | ||
615 | ++result; | ||
616 | break; | ||
617 | } | ||
618 | } | ||
619 | } | ||
620 | } | ||
621 | } | 620 | } |
622 | break; | 621 | break; |
623 | case AUDIT_ARG0: | 622 | case AUDIT_ARG0: |
@@ -1228,7 +1227,7 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) | |||
1228 | audit_log_format(ab, " cap_fe=%d cap_fver=%x", name->fcap.fE, name->fcap_ver); | 1227 | audit_log_format(ab, " cap_fe=%d cap_fver=%x", name->fcap.fE, name->fcap_ver); |
1229 | } | 1228 | } |
1230 | 1229 | ||
1231 | static void show_special(struct audit_context *context) | 1230 | static void show_special(struct audit_context *context, int *call_panic) |
1232 | { | 1231 | { |
1233 | struct audit_buffer *ab; | 1232 | struct audit_buffer *ab; |
1234 | int i; | 1233 | int i; |
@@ -1245,6 +1244,23 @@ static void show_special(struct audit_context *context) | |||
1245 | audit_log_format(ab, " a%d=%lx", i, | 1244 | audit_log_format(ab, " a%d=%lx", i, |
1246 | context->socketcall.args[i]); | 1245 | context->socketcall.args[i]); |
1247 | break; } | 1246 | break; } |
1247 | case AUDIT_IPC: { | ||
1248 | u32 osid = context->ipc.osid; | ||
1249 | |||
1250 | audit_log_format(ab, "ouid=%u ogid=%u mode=%#o", | ||
1251 | context->ipc.uid, context->ipc.gid, context->ipc.mode); | ||
1252 | if (osid) { | ||
1253 | char *ctx = NULL; | ||
1254 | u32 len; | ||
1255 | if (security_secid_to_secctx(osid, &ctx, &len)) { | ||
1256 | audit_log_format(ab, " osid=%u", osid); | ||
1257 | *call_panic = 1; | ||
1258 | } else { | ||
1259 | audit_log_format(ab, " obj=%s", ctx); | ||
1260 | security_release_secctx(ctx, len); | ||
1261 | } | ||
1262 | } | ||
1263 | break; } | ||
1248 | } | 1264 | } |
1249 | audit_log_end(ab); | 1265 | audit_log_end(ab); |
1250 | } | 1266 | } |
@@ -1363,26 +1379,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1363 | axi->mqstat.mq_msgsize, axi->mqstat.mq_curmsgs); | 1379 | axi->mqstat.mq_msgsize, axi->mqstat.mq_curmsgs); |
1364 | break; } | 1380 | break; } |
1365 | 1381 | ||
1366 | case AUDIT_IPC: { | ||
1367 | struct audit_aux_data_ipcctl *axi = (void *)aux; | ||
1368 | audit_log_format(ab, | ||
1369 | "ouid=%u ogid=%u mode=%#o", | ||
1370 | axi->uid, axi->gid, axi->mode); | ||
1371 | if (axi->osid != 0) { | ||
1372 | char *ctx = NULL; | ||
1373 | u32 len; | ||
1374 | if (security_secid_to_secctx( | ||
1375 | axi->osid, &ctx, &len)) { | ||
1376 | audit_log_format(ab, " osid=%u", | ||
1377 | axi->osid); | ||
1378 | call_panic = 1; | ||
1379 | } else { | ||
1380 | audit_log_format(ab, " obj=%s", ctx); | ||
1381 | security_release_secctx(ctx, len); | ||
1382 | } | ||
1383 | } | ||
1384 | break; } | ||
1385 | |||
1386 | case AUDIT_IPC_SET_PERM: { | 1382 | case AUDIT_IPC_SET_PERM: { |
1387 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 1383 | struct audit_aux_data_ipcctl *axi = (void *)aux; |
1388 | audit_log_format(ab, | 1384 | audit_log_format(ab, |
@@ -1427,7 +1423,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1427 | } | 1423 | } |
1428 | 1424 | ||
1429 | if (context->type) | 1425 | if (context->type) |
1430 | show_special(context); | 1426 | show_special(context, &call_panic); |
1431 | 1427 | ||
1432 | if (context->sockaddr_len) { | 1428 | if (context->sockaddr_len) { |
1433 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_SOCKADDR); | 1429 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_SOCKADDR); |
@@ -2349,25 +2345,15 @@ int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat) | |||
2349 | * audit_ipc_obj - record audit data for ipc object | 2345 | * audit_ipc_obj - record audit data for ipc object |
2350 | * @ipcp: ipc permissions | 2346 | * @ipcp: ipc permissions |
2351 | * | 2347 | * |
2352 | * Returns 0 for success or NULL context or < 0 on error. | ||
2353 | */ | 2348 | */ |
2354 | int __audit_ipc_obj(struct kern_ipc_perm *ipcp) | 2349 | void __audit_ipc_obj(struct kern_ipc_perm *ipcp) |
2355 | { | 2350 | { |
2356 | struct audit_aux_data_ipcctl *ax; | ||
2357 | struct audit_context *context = current->audit_context; | 2351 | struct audit_context *context = current->audit_context; |
2358 | 2352 | context->ipc.uid = ipcp->uid; | |
2359 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | 2353 | context->ipc.gid = ipcp->gid; |
2360 | if (!ax) | 2354 | context->ipc.mode = ipcp->mode; |
2361 | return -ENOMEM; | 2355 | security_ipc_getsecid(ipcp, &context->ipc.osid); |
2362 | 2356 | context->type = AUDIT_IPC; | |
2363 | ax->uid = ipcp->uid; | ||
2364 | ax->gid = ipcp->gid; | ||
2365 | ax->mode = ipcp->mode; | ||
2366 | security_ipc_getsecid(ipcp, &ax->osid); | ||
2367 | ax->d.type = AUDIT_IPC; | ||
2368 | ax->d.next = context->aux; | ||
2369 | context->aux = (void *)ax; | ||
2370 | return 0; | ||
2371 | } | 2357 | } |
2372 | 2358 | ||
2373 | /** | 2359 | /** |