diff options
| -rw-r--r-- | include/linux/audit.h | 9 | ||||
| -rw-r--r-- | ipc/util.c | 9 | ||||
| -rw-r--r-- | kernel/auditsc.c | 59 |
3 files changed, 32 insertions, 45 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index f8578b9088e1..b7abfe0d6737 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
| @@ -444,7 +444,7 @@ extern int audit_set_loginuid(struct task_struct *task, uid_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 void __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 void __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); |
| 450 | extern int audit_sockaddr(int len, void *addr); | 450 | extern int audit_sockaddr(int len, void *addr); |
| @@ -471,11 +471,10 @@ static inline int audit_fd_pair(int fd1, int fd2) | |||
| 471 | return __audit_fd_pair(fd1, fd2); | 471 | return __audit_fd_pair(fd1, fd2); |
| 472 | return 0; | 472 | return 0; |
| 473 | } | 473 | } |
| 474 | static inline int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) | 474 | static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) |
| 475 | { | 475 | { |
| 476 | if (unlikely(!audit_dummy_context())) | 476 | if (unlikely(!audit_dummy_context())) |
| 477 | return __audit_ipc_set_perm(qbytes, uid, gid, mode); | 477 | __audit_ipc_set_perm(qbytes, uid, gid, mode); |
| 478 | return 0; | ||
| 479 | } | 478 | } |
| 480 | static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr) | 479 | static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr) |
| 481 | { | 480 | { |
| @@ -546,7 +545,7 @@ extern int audit_signals; | |||
| 546 | #define audit_get_sessionid(t) (-1) | 545 | #define audit_get_sessionid(t) (-1) |
| 547 | #define audit_log_task_context(b) do { ; } while (0) | 546 | #define audit_log_task_context(b) do { ; } while (0) |
| 548 | #define audit_ipc_obj(i) ((void)0) | 547 | #define audit_ipc_obj(i) ((void)0) |
| 549 | #define audit_ipc_set_perm(q,u,g,m) ({ 0; }) | 548 | #define audit_ipc_set_perm(q,u,g,m) ((void)0) |
| 550 | #define audit_bprm(p) ({ 0; }) | 549 | #define audit_bprm(p) ({ 0; }) |
| 551 | #define audit_socketcall(n,a) ((void)0) | 550 | #define audit_socketcall(n,a) ((void)0) |
| 552 | #define audit_fd_pair(n,a) ({ 0; }) | 551 | #define audit_fd_pair(n,a) ({ 0; }) |
diff --git a/ipc/util.c b/ipc/util.c index 579552abd50a..7585a72e259b 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
| @@ -803,13 +803,9 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd, | |||
| 803 | } | 803 | } |
| 804 | 804 | ||
| 805 | audit_ipc_obj(ipcp); | 805 | audit_ipc_obj(ipcp); |
| 806 | 806 | if (cmd == IPC_SET) | |
| 807 | if (cmd == IPC_SET) { | 807 | audit_ipc_set_perm(extra_perm, perm->uid, |
| 808 | err = audit_ipc_set_perm(extra_perm, perm->uid, | ||
| 809 | perm->gid, perm->mode); | 808 | perm->gid, perm->mode); |
| 810 | if (err) | ||
| 811 | goto out_unlock; | ||
| 812 | } | ||
| 813 | 809 | ||
| 814 | euid = current_euid(); | 810 | euid = current_euid(); |
| 815 | if (euid == ipcp->cuid || | 811 | if (euid == ipcp->cuid || |
| @@ -817,7 +813,6 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd, | |||
| 817 | return ipcp; | 813 | return ipcp; |
| 818 | 814 | ||
| 819 | err = -EPERM; | 815 | err = -EPERM; |
| 820 | out_unlock: | ||
| 821 | ipc_unlock(ipcp); | 816 | ipc_unlock(ipcp); |
| 822 | out_up: | 817 | out_up: |
| 823 | up_write(&ids->rw_mutex); | 818 | up_write(&ids->rw_mutex); |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 73504313264f..fbed62e05bce 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -151,16 +151,6 @@ struct audit_aux_data_mq_getsetattr { | |||
| 151 | struct mq_attr mqstat; | 151 | struct mq_attr mqstat; |
| 152 | }; | 152 | }; |
| 153 | 153 | ||
| 154 | struct audit_aux_data_ipcctl { | ||
| 155 | struct audit_aux_data d; | ||
| 156 | struct ipc_perm p; | ||
| 157 | unsigned long qbytes; | ||
| 158 | uid_t uid; | ||
| 159 | gid_t gid; | ||
| 160 | mode_t mode; | ||
| 161 | u32 osid; | ||
| 162 | }; | ||
| 163 | |||
| 164 | struct audit_aux_data_execve { | 154 | struct audit_aux_data_execve { |
| 165 | struct audit_aux_data d; | 155 | struct audit_aux_data d; |
| 166 | int argc; | 156 | int argc; |
| @@ -252,6 +242,11 @@ struct audit_context { | |||
| 252 | gid_t gid; | 242 | gid_t gid; |
| 253 | mode_t mode; | 243 | mode_t mode; |
| 254 | u32 osid; | 244 | u32 osid; |
| 245 | int has_perm; | ||
| 246 | uid_t perm_uid; | ||
| 247 | gid_t perm_gid; | ||
| 248 | mode_t perm_mode; | ||
| 249 | unsigned long qbytes; | ||
| 255 | } ipc; | 250 | } ipc; |
| 256 | }; | 251 | }; |
| 257 | 252 | ||
| @@ -1260,6 +1255,19 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
| 1260 | security_release_secctx(ctx, len); | 1255 | security_release_secctx(ctx, len); |
| 1261 | } | 1256 | } |
| 1262 | } | 1257 | } |
| 1258 | if (context->ipc.has_perm) { | ||
| 1259 | audit_log_end(ab); | ||
| 1260 | ab = audit_log_start(context, GFP_KERNEL, | ||
| 1261 | AUDIT_IPC_SET_PERM); | ||
| 1262 | audit_log_format(ab, | ||
| 1263 | "qbytes=%lx ouid=%u ogid=%u mode=%#o", | ||
| 1264 | context->ipc.qbytes, | ||
| 1265 | context->ipc.perm_uid, | ||
| 1266 | context->ipc.perm_gid, | ||
| 1267 | context->ipc.perm_mode); | ||
| 1268 | if (!ab) | ||
| 1269 | return; | ||
| 1270 | } | ||
| 1263 | break; } | 1271 | break; } |
| 1264 | } | 1272 | } |
| 1265 | audit_log_end(ab); | 1273 | audit_log_end(ab); |
| @@ -1379,13 +1387,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
| 1379 | axi->mqstat.mq_msgsize, axi->mqstat.mq_curmsgs); | 1387 | axi->mqstat.mq_msgsize, axi->mqstat.mq_curmsgs); |
| 1380 | break; } | 1388 | break; } |
| 1381 | 1389 | ||
| 1382 | case AUDIT_IPC_SET_PERM: { | ||
| 1383 | struct audit_aux_data_ipcctl *axi = (void *)aux; | ||
| 1384 | audit_log_format(ab, | ||
| 1385 | "qbytes=%lx ouid=%u ogid=%u mode=%#o", | ||
| 1386 | axi->qbytes, axi->uid, axi->gid, axi->mode); | ||
| 1387 | break; } | ||
| 1388 | |||
| 1389 | case AUDIT_EXECVE: { | 1390 | case AUDIT_EXECVE: { |
| 1390 | struct audit_aux_data_execve *axi = (void *)aux; | 1391 | struct audit_aux_data_execve *axi = (void *)aux; |
| 1391 | audit_log_execve_info(context, &ab, axi); | 1392 | audit_log_execve_info(context, &ab, axi); |
| @@ -2352,6 +2353,7 @@ void __audit_ipc_obj(struct kern_ipc_perm *ipcp) | |||
| 2352 | context->ipc.uid = ipcp->uid; | 2353 | context->ipc.uid = ipcp->uid; |
| 2353 | context->ipc.gid = ipcp->gid; | 2354 | context->ipc.gid = ipcp->gid; |
| 2354 | context->ipc.mode = ipcp->mode; | 2355 | context->ipc.mode = ipcp->mode; |
| 2356 | context->ipc.has_perm = 0; | ||
| 2355 | security_ipc_getsecid(ipcp, &context->ipc.osid); | 2357 | security_ipc_getsecid(ipcp, &context->ipc.osid); |
| 2356 | context->type = AUDIT_IPC; | 2358 | context->type = AUDIT_IPC; |
| 2357 | } | 2359 | } |
| @@ -2363,26 +2365,17 @@ void __audit_ipc_obj(struct kern_ipc_perm *ipcp) | |||
| 2363 | * @gid: msgq group id | 2365 | * @gid: msgq group id |
| 2364 | * @mode: msgq mode (permissions) | 2366 | * @mode: msgq mode (permissions) |
| 2365 | * | 2367 | * |
| 2366 | * Returns 0 for success or NULL context or < 0 on error. | 2368 | * Called only after audit_ipc_obj(). |
| 2367 | */ | 2369 | */ |
| 2368 | int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) | 2370 | void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) |
| 2369 | { | 2371 | { |
| 2370 | struct audit_aux_data_ipcctl *ax; | ||
| 2371 | struct audit_context *context = current->audit_context; | 2372 | struct audit_context *context = current->audit_context; |
| 2372 | 2373 | ||
| 2373 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | 2374 | context->ipc.qbytes = qbytes; |
| 2374 | if (!ax) | 2375 | context->ipc.perm_uid = uid; |
| 2375 | return -ENOMEM; | 2376 | context->ipc.perm_gid = gid; |
| 2376 | 2377 | context->ipc.perm_mode = mode; | |
| 2377 | ax->qbytes = qbytes; | 2378 | context->ipc.has_perm = 1; |
| 2378 | ax->uid = uid; | ||
| 2379 | ax->gid = gid; | ||
| 2380 | ax->mode = mode; | ||
| 2381 | |||
| 2382 | ax->d.type = AUDIT_IPC_SET_PERM; | ||
| 2383 | ax->d.next = context->aux; | ||
| 2384 | context->aux = (void *)ax; | ||
| 2385 | return 0; | ||
| 2386 | } | 2379 | } |
| 2387 | 2380 | ||
| 2388 | int audit_bprm(struct linux_binprm *bprm) | 2381 | int audit_bprm(struct linux_binprm *bprm) |
