aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinda Knippers <linda.knippers@hp.com>2006-05-16 22:03:48 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2006-06-20 05:25:24 -0400
commitac03221a4fdda9bfdabf99bcd129847f20fc1d80 (patch)
tree9b65ede238b03007bfe5e25f46efca68ec0994e0
parent5d136a010de3bc16fe595987feb9ef8868f064c2 (diff)
[PATCH] update of IPC audit record cleanup
The following patch addresses most of the issues with the IPC_SET_PERM records as described in: https://www.redhat.com/archives/linux-audit/2006-May/msg00010.html and addresses the comments I received on the record field names. To summarize, I made the following changes: 1. Changed sys_msgctl() and semctl_down() so that an IPC_SET_PERM record is emitted in the failure case as well as the success case. This matches the behavior in sys_shmctl(). I could simplify the code in sys_msgctl() and semctl_down() slightly but it would mean that in some error cases we could get an IPC_SET_PERM record without an IPC record and that seemed odd. 2. No change to the IPC record type, given no feedback on the backward compatibility question. 3. Removed the qbytes field from the IPC record. It wasn't being set and when audit_ipc_obj() is called from ipcperms(), the information isn't available. If we want the information in the IPC record, more extensive changes will be necessary. Since it only applies to message queues and it isn't really permission related, it doesn't seem worth it. 4. Removed the obj field from the IPC_SET_PERM record. This means that the kern_ipc_perm argument is no longer needed. 5. Removed the spaces and renamed the IPC_SET_PERM field names. Replaced iuid and igid fields with ouid and ogid in the IPC record. I tested this with the lspp.22 kernel on an x86_64 box. I believe it applies cleanly on the latest kernel. -- ljk Signed-off-by: Linda Knippers <linda.knippers@hp.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--include/linux/audit.h4
-rw-r--r--ipc/msg.c9
-rw-r--r--ipc/sem.c8
-rw-r--r--ipc/shm.c2
-rw-r--r--kernel/auditsc.c22
5 files changed, 18 insertions, 27 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 8f6424f2b604..da5f521be04b 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -325,7 +325,7 @@ extern void auditsc_get_stamp(struct audit_context *ctx,
325extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); 325extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
326extern uid_t audit_get_loginuid(struct audit_context *ctx); 326extern uid_t audit_get_loginuid(struct audit_context *ctx);
327extern int audit_ipc_obj(struct kern_ipc_perm *ipcp); 327extern int audit_ipc_obj(struct kern_ipc_perm *ipcp);
328extern int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp); 328extern int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
329extern int audit_bprm(struct linux_binprm *bprm); 329extern int audit_bprm(struct linux_binprm *bprm);
330extern int audit_socketcall(int nargs, unsigned long *args); 330extern int audit_socketcall(int nargs, unsigned long *args);
331extern int audit_sockaddr(int len, void *addr); 331extern int audit_sockaddr(int len, void *addr);
@@ -345,7 +345,7 @@ extern int audit_set_macxattr(const char *name);
345#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0) 345#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
346#define audit_get_loginuid(c) ({ -1; }) 346#define audit_get_loginuid(c) ({ -1; })
347#define audit_ipc_obj(i) ({ 0; }) 347#define audit_ipc_obj(i) ({ 0; })
348#define audit_ipc_set_perm(q,u,g,m,i) ({ 0; }) 348#define audit_ipc_set_perm(q,u,g,m) ({ 0; })
349#define audit_bprm(p) ({ 0; }) 349#define audit_bprm(p) ({ 0; })
350#define audit_socketcall(n,a) ({ 0; }) 350#define audit_socketcall(n,a) ({ 0; })
351#define audit_sockaddr(len, addr) ({ 0; }) 351#define audit_sockaddr(len, addr) ({ 0; })
diff --git a/ipc/msg.c b/ipc/msg.c
index 7d1340ccb16b..00f015a092d2 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -454,6 +454,11 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
454 err = audit_ipc_obj(ipcp); 454 err = audit_ipc_obj(ipcp);
455 if (err) 455 if (err)
456 goto out_unlock_up; 456 goto out_unlock_up;
457 if (cmd==IPC_SET) {
458 err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode);
459 if (err)
460 goto out_unlock_up;
461 }
457 462
458 err = -EPERM; 463 err = -EPERM;
459 if (current->euid != ipcp->cuid && 464 if (current->euid != ipcp->cuid &&
@@ -468,10 +473,6 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
468 switch (cmd) { 473 switch (cmd) {
469 case IPC_SET: 474 case IPC_SET:
470 { 475 {
471 err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode, ipcp);
472 if (err)
473 goto out_unlock_up;
474
475 err = -EPERM; 476 err = -EPERM;
476 if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE)) 477 if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
477 goto out_unlock_up; 478 goto out_unlock_up;
diff --git a/ipc/sem.c b/ipc/sem.c
index 7919f8ece6ba..fce0bc8b5ad6 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -828,6 +828,11 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
828 if (err) 828 if (err)
829 goto out_unlock; 829 goto out_unlock;
830 830
831 if (cmd == IPC_SET) {
832 err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode);
833 if (err)
834 goto out_unlock;
835 }
831 if (current->euid != ipcp->cuid && 836 if (current->euid != ipcp->cuid &&
832 current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) { 837 current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) {
833 err=-EPERM; 838 err=-EPERM;
@@ -844,9 +849,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
844 err = 0; 849 err = 0;
845 break; 850 break;
846 case IPC_SET: 851 case IPC_SET:
847 err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode, ipcp);
848 if (err)
849 goto out_unlock;
850 ipcp->uid = setbuf.uid; 852 ipcp->uid = setbuf.uid;
851 ipcp->gid = setbuf.gid; 853 ipcp->gid = setbuf.gid;
852 ipcp->mode = (ipcp->mode & ~S_IRWXUGO) 854 ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
diff --git a/ipc/shm.c b/ipc/shm.c
index 809896851902..4f133d24030f 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -643,7 +643,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
643 err = audit_ipc_obj(&(shp->shm_perm)); 643 err = audit_ipc_obj(&(shp->shm_perm));
644 if (err) 644 if (err)
645 goto out_unlock_up; 645 goto out_unlock_up;
646 err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode, &(shp->shm_perm)); 646 err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode);
647 if (err) 647 if (err)
648 goto out_unlock_up; 648 goto out_unlock_up;
649 err=-EPERM; 649 err=-EPERM;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index e4551659ad79..fa4bf9625456 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -648,8 +648,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
648 case AUDIT_IPC: { 648 case AUDIT_IPC: {
649 struct audit_aux_data_ipcctl *axi = (void *)aux; 649 struct audit_aux_data_ipcctl *axi = (void *)aux;
650 audit_log_format(ab, 650 audit_log_format(ab,
651 " qbytes=%lx iuid=%u igid=%u mode=%x", 651 "ouid=%u ogid=%u mode=%x",
652 axi->qbytes, axi->uid, axi->gid, axi->mode); 652 axi->uid, axi->gid, axi->mode);
653 if (axi->osid != 0) { 653 if (axi->osid != 0) {
654 char *ctx = NULL; 654 char *ctx = NULL;
655 u32 len; 655 u32 len;
@@ -667,21 +667,10 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
667 case AUDIT_IPC_SET_PERM: { 667 case AUDIT_IPC_SET_PERM: {
668 struct audit_aux_data_ipcctl *axi = (void *)aux; 668 struct audit_aux_data_ipcctl *axi = (void *)aux;
669 audit_log_format(ab, 669 audit_log_format(ab,
670 " new qbytes=%lx new iuid=%u new igid=%u new mode=%x", 670 "qbytes=%lx ouid=%u ogid=%u mode=%x",
671 axi->qbytes, axi->uid, axi->gid, axi->mode); 671 axi->qbytes, axi->uid, axi->gid, axi->mode);
672 if (axi->osid != 0) {
673 char *ctx = NULL;
674 u32 len;
675 if (selinux_ctxid_to_string(
676 axi->osid, &ctx, &len)) {
677 audit_log_format(ab, " osid=%u",
678 axi->osid);
679 call_panic = 1;
680 } else
681 audit_log_format(ab, " obj=%s", ctx);
682 kfree(ctx);
683 }
684 break; } 672 break; }
673
685 case AUDIT_EXECVE: { 674 case AUDIT_EXECVE: {
686 struct audit_aux_data_execve *axi = (void *)aux; 675 struct audit_aux_data_execve *axi = (void *)aux;
687 int i; 676 int i;
@@ -1232,7 +1221,7 @@ int audit_ipc_obj(struct kern_ipc_perm *ipcp)
1232 * 1221 *
1233 * Returns 0 for success or NULL context or < 0 on error. 1222 * Returns 0 for success or NULL context or < 0 on error.
1234 */ 1223 */
1235int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp) 1224int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
1236{ 1225{
1237 struct audit_aux_data_ipcctl *ax; 1226 struct audit_aux_data_ipcctl *ax;
1238 struct audit_context *context = current->audit_context; 1227 struct audit_context *context = current->audit_context;
@@ -1248,7 +1237,6 @@ int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode,
1248 ax->uid = uid; 1237 ax->uid = uid;
1249 ax->gid = gid; 1238 ax->gid = gid;
1250 ax->mode = mode; 1239 ax->mode = mode;
1251 selinux_get_ipc_sid(ipcp, &ax->osid);
1252 1240
1253 ax->d.type = AUDIT_IPC_SET_PERM; 1241 ax->d.type = AUDIT_IPC_SET_PERM;
1254 ax->d.next = context->aux; 1242 ax->d.next = context->aux;