Skip to content

Commit

Permalink
[PATCH] update of IPC audit record cleanup
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Linda Knippers authored and Al Viro committed Jun 20, 2006
1 parent 5d136a0 commit ac03221
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 27 deletions.
4 changes: 2 additions & 2 deletions include/linux/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ extern void auditsc_get_stamp(struct audit_context *ctx,
extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
extern uid_t audit_get_loginuid(struct audit_context *ctx);
extern int audit_ipc_obj(struct kern_ipc_perm *ipcp);
extern int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp);
extern int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
extern int audit_bprm(struct linux_binprm *bprm);
extern int audit_socketcall(int nargs, unsigned long *args);
extern int audit_sockaddr(int len, void *addr);
Expand All @@ -345,7 +345,7 @@ extern int audit_set_macxattr(const char *name);
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
#define audit_get_loginuid(c) ({ -1; })
#define audit_ipc_obj(i) ({ 0; })
#define audit_ipc_set_perm(q,u,g,m,i) ({ 0; })
#define audit_ipc_set_perm(q,u,g,m) ({ 0; })
#define audit_bprm(p) ({ 0; })
#define audit_socketcall(n,a) ({ 0; })
#define audit_sockaddr(len, addr) ({ 0; })
Expand Down
9 changes: 5 additions & 4 deletions ipc/msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,11 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
err = audit_ipc_obj(ipcp);
if (err)
goto out_unlock_up;
if (cmd==IPC_SET) {
err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode);
if (err)
goto out_unlock_up;
}

err = -EPERM;
if (current->euid != ipcp->cuid &&
Expand All @@ -468,10 +473,6 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
switch (cmd) {
case IPC_SET:
{
err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode, ipcp);
if (err)
goto out_unlock_up;

err = -EPERM;
if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
goto out_unlock_up;
Expand Down
8 changes: 5 additions & 3 deletions ipc/sem.c
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,11 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
if (err)
goto out_unlock;

if (cmd == IPC_SET) {
err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode);
if (err)
goto out_unlock;
}
if (current->euid != ipcp->cuid &&
current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) {
err=-EPERM;
Expand All @@ -844,9 +849,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
err = 0;
break;
case IPC_SET:
err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode, ipcp);
if (err)
goto out_unlock;
ipcp->uid = setbuf.uid;
ipcp->gid = setbuf.gid;
ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
Expand Down
2 changes: 1 addition & 1 deletion ipc/shm.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
err = audit_ipc_obj(&(shp->shm_perm));
if (err)
goto out_unlock_up;
err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode, &(shp->shm_perm));
err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode);
if (err)
goto out_unlock_up;
err=-EPERM;
Expand Down
22 changes: 5 additions & 17 deletions kernel/auditsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,8 +648,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
case AUDIT_IPC: {
struct audit_aux_data_ipcctl *axi = (void *)aux;
audit_log_format(ab,
" qbytes=%lx iuid=%u igid=%u mode=%x",
axi->qbytes, axi->uid, axi->gid, axi->mode);
"ouid=%u ogid=%u mode=%x",
axi->uid, axi->gid, axi->mode);
if (axi->osid != 0) {
char *ctx = NULL;
u32 len;
Expand All @@ -667,21 +667,10 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
case AUDIT_IPC_SET_PERM: {
struct audit_aux_data_ipcctl *axi = (void *)aux;
audit_log_format(ab,
" new qbytes=%lx new iuid=%u new igid=%u new mode=%x",
"qbytes=%lx ouid=%u ogid=%u mode=%x",
axi->qbytes, axi->uid, axi->gid, axi->mode);
if (axi->osid != 0) {
char *ctx = NULL;
u32 len;
if (selinux_ctxid_to_string(
axi->osid, &ctx, &len)) {
audit_log_format(ab, " osid=%u",
axi->osid);
call_panic = 1;
} else
audit_log_format(ab, " obj=%s", ctx);
kfree(ctx);
}
break; }

case AUDIT_EXECVE: {
struct audit_aux_data_execve *axi = (void *)aux;
int i;
Expand Down Expand Up @@ -1232,7 +1221,7 @@ int audit_ipc_obj(struct kern_ipc_perm *ipcp)
*
* Returns 0 for success or NULL context or < 0 on error.
*/
int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp)
int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
{
struct audit_aux_data_ipcctl *ax;
struct audit_context *context = current->audit_context;
Expand All @@ -1248,7 +1237,6 @@ int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode,
ax->uid = uid;
ax->gid = gid;
ax->mode = mode;
selinux_get_ipc_sid(ipcp, &ax->osid);

ax->d.type = AUDIT_IPC_SET_PERM;
ax->d.next = context->aux;
Expand Down

0 comments on commit ac03221

Please sign in to comment.