aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/audit.h9
-rw-r--r--ipc/util.c9
-rw-r--r--kernel/auditsc.c59
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)
445extern void audit_log_task_context(struct audit_buffer *ab); 445extern void audit_log_task_context(struct audit_buffer *ab);
446extern void __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 void __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);
450extern int audit_sockaddr(int len, void *addr); 450extern 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}
474static inline int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) 474static 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}
480static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr) 479static 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;
820out_unlock:
821 ipc_unlock(ipcp); 816 ipc_unlock(ipcp);
822out_up: 817out_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
154struct 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
164struct audit_aux_data_execve { 154struct 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 */
2368int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) 2370void __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
2388int audit_bprm(struct linux_binprm *bprm) 2381int audit_bprm(struct linux_binprm *bprm)