aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-12-10 03:40:06 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2009-01-04 15:14:39 -0500
commita33e6751003c5ade603737d828b1519d980ce392 (patch)
treeaa484d033e886945aed78172dbdd4d2fd928bacf
parentf3298dc4f2277874d40cb4fc3a6e277317d6603b (diff)
sanitize audit_ipc_obj()
* 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.h9
-rw-r--r--ipc/shm.c4
-rw-r--r--ipc/util.c9
-rw-r--r--kernel/auditsc.c88
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)
445extern void audit_log_task_context(struct audit_buffer *ab); 445extern void audit_log_task_context(struct audit_buffer *ab);
446extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp); 446extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp);
447extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); 447extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
448extern int audit_bprm(struct linux_binprm *bprm); 448extern int audit_bprm(struct linux_binprm *bprm);
449extern void audit_socketcall(int nargs, unsigned long *args); 449extern 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);
461extern int __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old); 461extern int __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old);
462 462
463static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp) 463static 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}
469static inline int audit_fd_pair(int fd1, int fd2) 468static 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)
diff --git a/ipc/shm.c b/ipc/shm.c
index 38a055758a9b..57dd50046cef 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -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)
624int ipcperms (struct kern_ipc_perm *ipcp, short flag) 624int 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
1231static void show_special(struct audit_context *context) 1230static 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 */
2354int __audit_ipc_obj(struct kern_ipc_perm *ipcp) 2349void __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/**