diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-12-10 03:47:15 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-01-04 15:14:40 -0500 |
commit | e816f370cbadd2afea9f1a42f232d0636137d563 (patch) | |
tree | 8a9fe488ced59cd9864fcbf15292641c3b95143c | |
parent | a33e6751003c5ade603737d828b1519d980ce392 (diff) |
sanitize audit_ipc_set_perm()
* get rid of allocations
* make it return void
* simplify callers
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-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) |