Commit a0110032 authored by David Woodhouse's avatar David Woodhouse

Merge shinybook.infradead.org:/home/dwmw2/bk/linus-2.6

into shinybook.infradead.org:/home/dwmw2/bk/audit-2.6
parents a847f564 e20ffd76
......@@ -150,6 +150,7 @@ extern void audit_get_stamp(struct audit_context *ctx,
struct timespec *t, int *serial);
extern int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid);
extern uid_t audit_get_loginuid(struct audit_context *ctx);
extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
......@@ -159,6 +160,7 @@ extern uid_t audit_get_loginuid(struct audit_context *ctx);
#define audit_putname(n) do { ; } while (0)
#define audit_inode(n,i,d) do { ; } while (0)
#define audit_get_loginuid(c) ({ -1; })
#define audit_ipc_perms(q,u,g,m) ({ 0; })
#endif
#ifdef CONFIG_AUDIT
......
......@@ -25,6 +25,7 @@
#include <linux/security.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
#include <linux/audit.h>
#include <asm/current.h>
#include <asm/uaccess.h>
#include "util.h"
......@@ -425,6 +426,8 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
return -EFAULT;
if (copy_msqid_from_user (&setbuf, buf, version))
return -EFAULT;
if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode)))
return err;
break;
case IPC_RMID:
break;
......
......@@ -72,6 +72,7 @@
#include <linux/smp_lock.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/audit.h>
#include <asm/uaccess.h>
#include "util.h"
......@@ -803,6 +804,8 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
if(cmd == IPC_SET) {
if(copy_semid_from_user (&setbuf, arg.buf, version))
return -EFAULT;
if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
return err;
}
sma = sem_lock(semid);
if(sma==NULL)
......
......@@ -27,6 +27,7 @@
#include <linux/shmem_fs.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/audit.h>
#include <asm/uaccess.h>
#include "util.h"
......@@ -600,6 +601,8 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
err = -EFAULT;
goto out;
}
if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
return err;
down(&shm_ids.sem);
shp = shm_lock(shmid);
err=-EINVAL;
......
......@@ -92,6 +92,23 @@ struct audit_names {
dev_t rdev;
};
struct audit_aux_data {
struct audit_aux_data *next;
int type;
};
#define AUDIT_AUX_IPCPERM 0
struct audit_aux_data_ipcctl {
struct audit_aux_data d;
struct ipc_perm p;
unsigned long qbytes;
uid_t uid;
gid_t gid;
mode_t mode;
};
/* The per-task audit context. */
struct audit_context {
int in_syscall; /* 1 if task is in a syscall */
......@@ -107,6 +124,7 @@ struct audit_context {
int name_count;
struct audit_names names[AUDIT_NAMES];
struct audit_context *previous; /* For nested syscalls */
struct audit_aux_data *aux;
/* Save things to print about task_struct */
pid_t pid;
......@@ -504,6 +522,16 @@ static inline void audit_free_names(struct audit_context *context)
context->name_count = 0;
}
static inline void audit_free_aux(struct audit_context *context)
{
struct audit_aux_data *aux;
while ((aux = context->aux)) {
context->aux = aux->next;
kfree(aux);
}
}
static inline void audit_zero_context(struct audit_context *context,
enum audit_state state)
{
......@@ -570,6 +598,7 @@ static inline void audit_free_context(struct audit_context *context)
context->name_count, count);
}
audit_free_names(context);
audit_free_aux(context);
kfree(context);
context = previous;
} while (context);
......@@ -607,6 +636,29 @@ static void audit_log_exit(struct audit_context *context)
context->euid, context->suid, context->fsuid,
context->egid, context->sgid, context->fsgid);
audit_log_end(ab);
while (context->aux) {
struct audit_aux_data *aux;
ab = audit_log_start(context);
if (!ab)
continue; /* audit_panic has been called */
aux = context->aux;
context->aux = aux->next;
audit_log_format(ab, "auxitem=%d", aux->type);
switch (aux->type) {
case AUDIT_AUX_IPCPERM: {
struct audit_aux_data_ipcctl *axi = (void *)aux;
audit_log_format(ab,
" qbytes=%lx uid=%d gid=%d mode=%x",
axi->qbytes, axi->uid, axi->gid, axi->mode);
}
}
audit_log_end(ab);
kfree(aux);
}
for (i = 0; i < context->name_count; i++) {
ab = audit_log_start(context);
if (!ab)
......@@ -789,6 +841,7 @@ void audit_syscall_exit(struct task_struct *tsk, int return_code)
tsk->audit_context = new_context;
} else {
audit_free_names(context);
audit_free_aux(context);
audit_zero_context(context, context->state);
tsk->audit_context = context;
}
......@@ -927,3 +980,26 @@ uid_t audit_get_loginuid(struct audit_context *ctx)
{
return ctx ? ctx->loginuid : -1;
}
int audit_ipc_perms(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;
if (likely(!context))
return 0;
ax = kmalloc(sizeof(*ax), GFP_KERNEL);
if (!ax)
return -ENOMEM;
ax->qbytes = qbytes;
ax->uid = uid;
ax->gid = gid;
ax->mode = mode;
ax->d.type = AUDIT_AUX_IPCPERM;
ax->d.next = context->aux;
context->aux = (void *)ax;
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment