Commit 1b9a3917 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'audit.b3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current

* 'audit.b3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current: (22 commits)
  [PATCH] fix audit_init failure path
  [PATCH] EXPORT_SYMBOL patch for audit_log, audit_log_start, audit_log_end and audit_format
  [PATCH] sem2mutex: audit_netlink_sem
  [PATCH] simplify audit_free() locking
  [PATCH] Fix audit operators
  [PATCH] promiscuous mode
  [PATCH] Add tty to syscall audit records
  [PATCH] add/remove rule update
  [PATCH] audit string fields interface + consumer
  [PATCH] SE Linux audit events
  [PATCH] Minor cosmetic cleanups to the code moved into auditfilter.c
  [PATCH] Fix audit record filtering with !CONFIG_AUDITSYSCALL
  [PATCH] Fix IA64 success/failure indication in syscall auditing.
  [PATCH] Miscellaneous bug and warning fixes
  [PATCH] Capture selinux subject/object context information.
  [PATCH] Exclude messages by message type
  [PATCH] Collect more inode information during syscall processing.
  [PATCH] Pass dentry, not just name, in fsnotify creation hooks.
  [PATCH] Define new range of userspace messages.
  [PATCH] Filter rule comparators
  ...

Fixed trivial conflict in security/selinux/hooks.c
parents 3661f00e 71e1c784
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/audit.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -252,6 +253,7 @@ asmlinkage int sys_vm86(struct pt_regs regs) ...@@ -252,6 +253,7 @@ asmlinkage int sys_vm86(struct pt_regs regs)
static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk)
{ {
struct tss_struct *tss; struct tss_struct *tss;
long eax;
/* /*
* make sure the vm86() system call doesn't try to do anything silly * make sure the vm86() system call doesn't try to do anything silly
*/ */
...@@ -305,13 +307,19 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk ...@@ -305,13 +307,19 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
tsk->thread.screen_bitmap = info->screen_bitmap; tsk->thread.screen_bitmap = info->screen_bitmap;
if (info->flags & VM86_SCREEN_BITMAP) if (info->flags & VM86_SCREEN_BITMAP)
mark_screen_rdonly(tsk->mm); mark_screen_rdonly(tsk->mm);
__asm__ __volatile__("xorl %eax,%eax; movl %eax,%fs; movl %eax,%gs\n\t");
__asm__ __volatile__("movl %%eax, %0\n" :"=r"(eax));
/*call audit_syscall_exit since we do not exit via the normal paths */
if (unlikely(current->audit_context))
audit_syscall_exit(current, AUDITSC_RESULT(eax), eax);
__asm__ __volatile__( __asm__ __volatile__(
"xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs\n\t"
"movl %0,%%esp\n\t" "movl %0,%%esp\n\t"
"movl %1,%%ebp\n\t" "movl %1,%%ebp\n\t"
"jmp resume_userspace" "jmp resume_userspace"
: /* no outputs */ : /* no outputs */
:"r" (&info->regs), "r" (task_thread_info(tsk)) : "ax"); :"r" (&info->regs), "r" (task_thread_info(tsk)));
/* we never return here */ /* we never return here */
} }
......
...@@ -1656,8 +1656,14 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3, ...@@ -1656,8 +1656,14 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
long arg4, long arg5, long arg6, long arg7, long arg4, long arg5, long arg6, long arg7,
struct pt_regs regs) struct pt_regs regs)
{ {
if (unlikely(current->audit_context)) if (unlikely(current->audit_context)) {
audit_syscall_exit(current, AUDITSC_RESULT(regs.r10), regs.r8); int success = AUDITSC_RESULT(regs.r10);
long result = regs.r8;
if (success != AUDITSC_SUCCESS)
result = -result;
audit_syscall_exit(current, success, result);
}
if (test_thread_flag(TIF_SYSCALL_TRACE) if (test_thread_flag(TIF_SYSCALL_TRACE)
&& (current->ptrace & PT_PTRACED)) && (current->ptrace & PT_PTRACED))
......
...@@ -1353,6 +1353,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir) ...@@ -1353,6 +1353,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
return -ENOENT; return -ENOENT;
BUG_ON(victim->d_parent->d_inode != dir); BUG_ON(victim->d_parent->d_inode != dir);
audit_inode_child(victim->d_name.name, victim->d_inode, dir->i_ino);
error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
if (error) if (error)
...@@ -1472,7 +1473,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, ...@@ -1472,7 +1473,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
DQUOT_INIT(dir); DQUOT_INIT(dir);
error = dir->i_op->create(dir, dentry, mode, nd); error = dir->i_op->create(dir, dentry, mode, nd);
if (!error) if (!error)
fsnotify_create(dir, dentry->d_name.name); fsnotify_create(dir, dentry);
return error; return error;
} }
...@@ -1799,7 +1800,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) ...@@ -1799,7 +1800,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
DQUOT_INIT(dir); DQUOT_INIT(dir);
error = dir->i_op->mknod(dir, dentry, mode, dev); error = dir->i_op->mknod(dir, dentry, mode, dev);
if (!error) if (!error)
fsnotify_create(dir, dentry->d_name.name); fsnotify_create(dir, dentry);
return error; return error;
} }
...@@ -1876,7 +1877,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -1876,7 +1877,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
DQUOT_INIT(dir); DQUOT_INIT(dir);
error = dir->i_op->mkdir(dir, dentry, mode); error = dir->i_op->mkdir(dir, dentry, mode);
if (!error) if (!error)
fsnotify_mkdir(dir, dentry->d_name.name); fsnotify_mkdir(dir, dentry);
return error; return error;
} }
...@@ -2139,7 +2140,7 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, i ...@@ -2139,7 +2140,7 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, i
DQUOT_INIT(dir); DQUOT_INIT(dir);
error = dir->i_op->symlink(dir, dentry, oldname); error = dir->i_op->symlink(dir, dentry, oldname);
if (!error) if (!error)
fsnotify_create(dir, dentry->d_name.name); fsnotify_create(dir, dentry);
return error; return error;
} }
...@@ -2216,7 +2217,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de ...@@ -2216,7 +2217,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
error = dir->i_op->link(old_dentry, dir, new_dentry); error = dir->i_op->link(old_dentry, dir, new_dentry);
mutex_unlock(&old_dentry->d_inode->i_mutex); mutex_unlock(&old_dentry->d_inode->i_mutex);
if (!error) if (!error)
fsnotify_create(dir, new_dentry->d_name.name); fsnotify_create(dir, new_dentry);
return error; return error;
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <linux/audit.h>
#include <asm/unistd.h> #include <asm/unistd.h>
...@@ -626,6 +627,8 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) ...@@ -626,6 +627,8 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
dentry = file->f_dentry; dentry = file->f_dentry;
inode = dentry->d_inode; inode = dentry->d_inode;
audit_inode(NULL, inode, 0);
err = -EROFS; err = -EROFS;
if (IS_RDONLY(inode)) if (IS_RDONLY(inode))
goto out_putf; goto out_putf;
...@@ -775,7 +778,10 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group) ...@@ -775,7 +778,10 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
file = fget(fd); file = fget(fd);
if (file) { if (file) {
error = chown_common(file->f_dentry, user, group); struct dentry * dentry;
dentry = file->f_dentry;
audit_inode(NULL, dentry->d_inode, 0);
error = chown_common(dentry, user, group);
fput(file); fput(file);
} }
return error; return error;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/fsnotify.h> #include <linux/fsnotify.h>
#include <linux/audit.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -234,12 +235,15 @@ sys_fsetxattr(int fd, char __user *name, void __user *value, ...@@ -234,12 +235,15 @@ sys_fsetxattr(int fd, char __user *name, void __user *value,
size_t size, int flags) size_t size, int flags)
{ {
struct file *f; struct file *f;
struct dentry *dentry;
int error = -EBADF; int error = -EBADF;
f = fget(fd); f = fget(fd);
if (!f) if (!f)
return error; return error;
error = setxattr(f->f_dentry, name, value, size, flags); dentry = f->f_dentry;
audit_inode(NULL, dentry->d_inode, 0);
error = setxattr(dentry, name, value, size, flags);
fput(f); fput(f);
return error; return error;
} }
...@@ -458,12 +462,15 @@ asmlinkage long ...@@ -458,12 +462,15 @@ asmlinkage long
sys_fremovexattr(int fd, char __user *name) sys_fremovexattr(int fd, char __user *name)
{ {
struct file *f; struct file *f;
struct dentry *dentry;
int error = -EBADF; int error = -EBADF;
f = fget(fd); f = fget(fd);
if (!f) if (!f)
return error; return error;
error = removexattr(f->f_dentry, name); dentry = f->f_dentry;
audit_inode(NULL, dentry->d_inode, 0);
error = removexattr(dentry, name);
fput(f); fput(f);
return error; return error;
} }
......
This diff is collapsed.
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/dnotify.h> #include <linux/dnotify.h>
#include <linux/inotify.h> #include <linux/inotify.h>
#include <linux/audit.h>
/* /*
* fsnotify_d_instantiate - instantiate a dentry for inode * fsnotify_d_instantiate - instantiate a dentry for inode
...@@ -64,6 +65,8 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, ...@@ -64,6 +65,8 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
if (source) { if (source) {
inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL); inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL);
} }
audit_inode_child(old_name, source, old_dir->i_ino);
audit_inode_child(new_name, target, new_dir->i_ino);
} }
/* /*
...@@ -89,19 +92,22 @@ static inline void fsnotify_inoderemove(struct inode *inode) ...@@ -89,19 +92,22 @@ static inline void fsnotify_inoderemove(struct inode *inode)
/* /*
* fsnotify_create - 'name' was linked in * fsnotify_create - 'name' was linked in
*/ */
static inline void fsnotify_create(struct inode *inode, const char *name) static inline void fsnotify_create(struct inode *inode, struct dentry *dentry)
{ {
inode_dir_notify(inode, DN_CREATE); inode_dir_notify(inode, DN_CREATE);
inotify_inode_queue_event(inode, IN_CREATE, 0, name); inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name);
audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino);
} }
/* /*
* fsnotify_mkdir - directory 'name' was created * fsnotify_mkdir - directory 'name' was created
*/ */
static inline void fsnotify_mkdir(struct inode *inode, const char *name) static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
{ {
inode_dir_notify(inode, DN_CREATE); inode_dir_notify(inode, DN_CREATE);
inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0, name); inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0,
dentry->d_name.name);
audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino);
} }
/* /*
......
...@@ -869,6 +869,11 @@ struct swap_info_struct; ...@@ -869,6 +869,11 @@ struct swap_info_struct;
* @ipcp contains the kernel IPC permission structure * @ipcp contains the kernel IPC permission structure
* @flag contains the desired (requested) permission set * @flag contains the desired (requested) permission set
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @ipc_getsecurity:
* Copy the security label associated with the ipc object into
* @buffer. @buffer may be NULL to request the size of the buffer
* required. @size indicates the size of @buffer in bytes. Return
* number of bytes used/required on success.
* *
* Security hooks for individual messages held in System V IPC message queues * Security hooks for individual messages held in System V IPC message queues
* @msg_msg_alloc_security: * @msg_msg_alloc_security:
...@@ -1168,7 +1173,8 @@ struct security_operations { ...@@ -1168,7 +1173,8 @@ struct security_operations {
int (*inode_getxattr) (struct dentry *dentry, char *name); int (*inode_getxattr) (struct dentry *dentry, char *name);
int (*inode_listxattr) (struct dentry *dentry); int (*inode_listxattr) (struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name); int (*inode_removexattr) (struct dentry *dentry, char *name);
int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size, int err); const char *(*inode_xattr_getsuffix) (void);
int (*inode_getsecurity)(const struct inode *inode, const char *name, void *buffer, size_t size, int err);
int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags); int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size); int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);
...@@ -1217,6 +1223,7 @@ struct security_operations { ...@@ -1217,6 +1223,7 @@ struct security_operations {
void (*task_to_inode)(struct task_struct *p, struct inode *inode); void (*task_to_inode)(struct task_struct *p, struct inode *inode);
int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag); int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag);
int (*ipc_getsecurity)(struct kern_ipc_perm *ipcp, void *buffer, size_t size);
int (*msg_msg_alloc_security) (struct msg_msg * msg); int (*msg_msg_alloc_security) (struct msg_msg * msg);
void (*msg_msg_free_security) (struct msg_msg * msg); void (*msg_msg_free_security) (struct msg_msg * msg);
...@@ -1680,7 +1687,12 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name) ...@@ -1680,7 +1687,12 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return security_ops->inode_removexattr (dentry, name); return security_ops->inode_removexattr (dentry, name);
} }
static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) static inline const char *security_inode_xattr_getsuffix(void)
{
return security_ops->inode_xattr_getsuffix();
}
static inline int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
{ {
if (unlikely (IS_PRIVATE (inode))) if (unlikely (IS_PRIVATE (inode)))
return 0; return 0;
...@@ -1875,6 +1887,11 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp, ...@@ -1875,6 +1887,11 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp,
return security_ops->ipc_permission (ipcp, flag); return security_ops->ipc_permission (ipcp, flag);
} }
static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
{
return security_ops->ipc_getsecurity(ipcp, buffer, size);
}
static inline int security_msg_msg_alloc (struct msg_msg * msg) static inline int security_msg_msg_alloc (struct msg_msg * msg)
{ {
return security_ops->msg_msg_alloc_security (msg); return security_ops->msg_msg_alloc_security (msg);
...@@ -2327,7 +2344,12 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name) ...@@ -2327,7 +2344,12 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return cap_inode_removexattr(dentry, name); return cap_inode_removexattr(dentry, name);
} }
static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) static inline const char *security_inode_xattr_getsuffix (void)
{
return NULL ;
}
static inline int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -2510,6 +2532,11 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp, ...@@ -2510,6 +2532,11 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp,
return 0; return 0;
} }
static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
{
return -EOPNOTSUPP;
}
static inline int security_msg_msg_alloc (struct msg_msg * msg) static inline int security_msg_msg_alloc (struct msg_msg * msg)
{ {
return 0; return 0;
......
...@@ -428,8 +428,6 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf) ...@@ -428,8 +428,6 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
return -EFAULT; return -EFAULT;
if (copy_msqid_from_user (&setbuf, buf, version)) if (copy_msqid_from_user (&setbuf, buf, version))
return -EFAULT; return -EFAULT;
if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode)))
return err;
break; break;
case IPC_RMID: case IPC_RMID:
break; break;
...@@ -460,6 +458,9 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf) ...@@ -460,6 +458,9 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
switch (cmd) { switch (cmd) {
case IPC_SET: case IPC_SET:
{ {
if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode, ipcp)))
goto out_unlock_up;
err = -EPERM; err = -EPERM;
if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE)) if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
goto out_unlock_up; goto out_unlock_up;
......
...@@ -809,8 +809,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun ...@@ -809,8 +809,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
if(cmd == IPC_SET) { if(cmd == IPC_SET) {
if(copy_semid_from_user (&setbuf, arg.buf, version)) if(copy_semid_from_user (&setbuf, arg.buf, version))
return -EFAULT; return -EFAULT;
if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
return err;
} }
sma = sem_lock(semid); sma = sem_lock(semid);
if(sma==NULL) if(sma==NULL)
...@@ -821,7 +819,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun ...@@ -821,7 +819,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
goto out_unlock; goto out_unlock;
} }
ipcp = &sma->sem_perm; ipcp = &sma->sem_perm;
if (current->euid != ipcp->cuid && if (current->euid != ipcp->cuid &&
current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) { current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) {
err=-EPERM; err=-EPERM;
...@@ -838,6 +835,8 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun ...@@ -838,6 +835,8 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
err = 0; err = 0;
break; break;
case IPC_SET: case IPC_SET:
if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode, ipcp)))
goto out_unlock;
ipcp->uid = setbuf.uid; ipcp->uid = setbuf.uid;
ipcp->gid = setbuf.gid; ipcp->gid = setbuf.gid;
ipcp->mode = (ipcp->mode & ~S_IRWXUGO) ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
......
...@@ -620,13 +620,13 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) ...@@ -620,13 +620,13 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
err = -EFAULT; err = -EFAULT;
goto out; goto out;
} }
if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
return err;
down(&shm_ids.sem); down(&shm_ids.sem);
shp = shm_lock(shmid); shp = shm_lock(shmid);
err=-EINVAL; err=-EINVAL;
if(shp==NULL) if(shp==NULL)
goto out_up; goto out_up;
if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode, &(shp->shm_perm))))
goto out_unlock_up;
err = shm_checkid(shp,shmid); err = shm_checkid(shp,shmid);
if(err) if(err)
goto out_unlock_up; goto out_unlock_up;
......
...@@ -26,7 +26,7 @@ obj-$(CONFIG_COMPAT) += compat.o ...@@ -26,7 +26,7 @@ obj-$(CONFIG_COMPAT) += compat.o
obj-$(CONFIG_CPUSETS) += cpuset.o obj-$(CONFIG_CPUSETS) += cpuset.o
obj-$(CONFIG_IKCONFIG) += configs.o obj-$(CONFIG_IKCONFIG) += configs.o
obj-$(CONFIG_STOP_MACHINE) += stop_machine.o obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_AUDIT) += audit.o auditfilter.o
obj-$(CONFIG_AUDITSYSCALL) += auditsc.o obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_SYSFS) += ksysfs.o obj-$(CONFIG_SYSFS) += ksysfs.o
......
This diff is collapsed.
/* audit -- definition of audit_context structure and supporting types
*
* Copyright 2003-2004 Red Hat, Inc.
* Copyright 2005 Hewlett-Packard Development Company, L.P.
* Copyright 2005 IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/mutex.h>
#include <linux/fs.h>
#include <linux/audit.h>
/* 0 = no checking
1 = put_count checking
2 = verbose put_count checking
*/
#define AUDIT_DEBUG 0
/* At task start time, the audit_state is set in the audit_context using
a per-task filter. At syscall entry, the audit_state is augmented by
the syscall filter. */
enum audit_state {
AUDIT_DISABLED, /* Do not create per-task audit_context.
* No syscall-specific audit records can
* be generated. */
AUDIT_SETUP_CONTEXT, /* Create the per-task audit_context,
* but don't necessarily fill it in at
* syscall entry time (i.e., filter
* instead). */
AUDIT_BUILD_CONTEXT, /* Create the per-task audit_context,
* and always fill it in at syscall
* entry time. This makes a full
* syscall record available if some
* other part of the kernel decides it
* should be recorded. */
AUDIT_RECORD_CONTEXT /* Create the per-task audit_context,
* always fill it in at syscall entry
* time, and always write out the audit
* record at syscall exit time. */
};
/* Rule lists */
struct audit_field {
u32 type;
u32 val;
u32 op;
};
struct audit_krule {
int vers_ops;
u32 flags;
u32 listnr;
u32 action;
u32 mask[AUDIT_BITMASK_SIZE];
u32 buflen; /* for data alloc on list rules */
u32 field_count;
struct audit_field *fields;
};
struct audit_entry {
struct list_head list;
struct rcu_head rcu;
struct audit_krule rule;
};
extern int audit_pid;
extern int audit_comparator(const u32 left, const u32 op, const u32 right);
extern void audit_send_reply(int pid, int seq, int type,
int done, int multi,
void *payload, int size);
extern void audit_log_lost(const char *message);
extern void audit_panic(const char *message);
extern struct mutex audit_netlink_mutex;
This diff is collapsed.
This diff is collapsed.
...@@ -114,6 +114,7 @@ ...@@ -114,6 +114,7 @@
#include <linux/wireless.h> #include <linux/wireless.h>
#include <net/iw_handler.h> #include <net/iw_handler.h>
#include <asm/current.h> #include <asm/current.h>
#include <linux/audit.h>
/* /*
* The list of packet types we will receive (as opposed to discard) * The list of packet types we will receive (as opposed to discard)
...@@ -2147,6 +2148,12 @@ void dev_set_promiscuity(struct net_device *dev, int inc) ...@@ -2147,6 +2148,12 @@ void dev_set_promiscuity(struct net_device *dev, int inc)
printk(KERN_INFO "device %s %s promiscuous mode\n", printk(KERN_INFO "device %s %s promiscuous mode\n",
dev->name, (dev->flags & IFF_PROMISC) ? "entered" : dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
"left"); "left");
audit_log(current->audit_context, GFP_ATOMIC,
AUDIT_ANOM_PROMISCUOUS,
"dev=%s prom=%d old_prom=%d auid=%u",
dev->name, (dev->flags & IFF_PROMISC),
(old_flags & IFF_PROMISC),
audit_get_loginuid(current->audit_context));
} }
} }
......
...@@ -378,7 +378,7 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name) ...@@ -378,7 +378,7 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name)
return 0; return 0;
} }
static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) static int dummy_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -393,6 +393,11 @@ static int dummy_inode_listsecurity(struct inode *inode, char *buffer, size_t bu ...@@ -393,6 +393,11 @@ static int dummy_inode_listsecurity(struct inode *inode, char *buffer, size_t bu
return 0; return 0;
} }
static const char *dummy_inode_xattr_getsuffix(void)
{
return NULL;
}
static int dummy_file_permission (struct file *file, int mask) static int dummy_file_permission (struct file *file, int mask)
{ {
return 0; return 0;
...@@ -558,6 +563,11 @@ static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag) ...@@ -558,6 +563,11 @@ static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag)
return 0; return 0;
} }
static int dummy_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
{
return -EOPNOTSUPP;
}
static int dummy_msg_msg_alloc_security (struct msg_msg *msg) static int dummy_msg_msg_alloc_security (struct msg_msg *msg)
{ {
return 0; return 0;
...@@ -931,6 +941,7 @@ void security_fixup_ops (struct security_operations *ops) ...@@ -931,6 +941,7 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, inode_getxattr); set_to_dummy_if_null(ops, inode_getxattr);
set_to_dummy_if_null(ops, inode_listxattr); set_to_dummy_if_null(ops, inode_listxattr);
set_to_dummy_if_null(ops, inode_removexattr); set_to_dummy_if_null(ops, inode_removexattr);
set_to_dummy_if_null(ops, inode_xattr_getsuffix);
set_to_dummy_if_null(ops, inode_getsecurity); set_to_dummy_if_null(ops, inode_getsecurity);
set_to_dummy_if_null(ops, inode_setsecurity); set_to_dummy_if_null(ops, inode_setsecurity);
set_to_dummy_if_null(ops, inode_listsecurity); set_to_dummy_if_null(ops, inode_listsecurity);
...@@ -965,6 +976,7 @@ void security_fixup_ops (struct security_operations *ops) ...@@ -965,6 +976,7 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, task_reparent_to_init); set_to_dummy_if_null(ops, task_reparent_to_init);
set_to_dummy_if_null(ops, task_to_inode); set_to_dummy_if_null(ops, task_to_inode);
set_to_dummy_if_null(ops, ipc_permission); set_to_dummy_if_null(ops, ipc_permission);
set_to_dummy_if_null(ops, ipc_getsecurity);
set_to_dummy_if_null(ops, msg_msg_alloc_security); set_to_dummy_if_null(ops, msg_msg_alloc_security);
set_to_dummy_if_null(ops, msg_msg_free_security); set_to_dummy_if_null(ops, msg_msg_free_security);
set_to_dummy_if_null(ops, msg_queue_alloc_security); set_to_dummy_if_null(ops, msg_queue_alloc_security);
......
...@@ -119,6 +119,32 @@ static DEFINE_SPINLOCK(sb_security_lock); ...@@ -119,6 +119,32 @@ static DEFINE_SPINLOCK(sb_security_lock);
static kmem_cache_t *sel_inode_cache; static kmem_cache_t *sel_inode_cache;
/* Return security context for a given sid or just the context
length if the buffer is null or length is 0 */
static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
{
char *context;
unsigned len;
int rc;
rc = security_sid_to_context(sid, &context, &len);
if (rc)
return rc;
if (!buffer || !size)
goto getsecurity_exit;
if (size < len) {
len = -ERANGE;
goto getsecurity_exit;
}
memcpy(buffer, context, len);
getsecurity_exit:
kfree(context);
return len;
}
/* Allocate and free functions for each kind of security blob. */ /* Allocate and free functions for each kind of security blob. */
static int task_alloc_security(struct task_struct *task) static int task_alloc_security(struct task_struct *task)
...@@ -2210,6 +2236,11 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name) ...@@ -2210,6 +2236,11 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
return -EACCES; return -EACCES;
} }
static const char *selinux_inode_xattr_getsuffix(void)
{
return XATTR_SELINUX_SUFFIX;
}
/* /*
* Copy the in-core inode security context value to the user. If the * Copy the in-core inode security context value to the user. If the
* getxattr() prior to this succeeded, check to see if we need to * getxattr() prior to this succeeded, check to see if we need to
...@@ -2217,47 +2248,14 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name) ...@@ -2217,47 +2248,14 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
* *
* Permission check is handled by selinux_inode_getxattr hook. * Permission check is handled by selinux_inode_getxattr hook.
*/ */
static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
{ {
struct inode_security_struct *isec = inode->i_security; struct inode_security_struct *isec = inode->i_security;
char *context;
unsigned len;
int rc;
if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
rc = -EOPNOTSUPP;
goto out;
}
rc = security_sid_to_context(isec->sid, &context, &len);
if (rc)
goto out;
/* Probe for required buffer size */
if (!buffer || !size) {
rc = len;
goto out_free;
}
if (size < len) { if (strcmp(name, XATTR_SELINUX_SUFFIX))
rc = -ERANGE; return -EOPNOTSUPP;
goto out_free;
}
if (err > 0) { return selinux_getsecurity(isec->sid, buffer, size);
if ((len == err) && !(memcmp(context, buffer, len))) {
/* Don't need to canonicalize value */
rc = err;
goto out_free;
}
memset(buffer, 0, size);
}
memcpy(buffer, context, len);
rc = len;
out_free:
kfree(context);
out:
return rc;
} }
static int selinux_inode_setsecurity(struct inode *inode, const char *name, static int selinux_inode_setsecurity(struct inode *inode, const char *name,
...@@ -4054,6 +4052,13 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) ...@@ -4054,6 +4052,13 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
return ipc_has_perm(ipcp, av); return ipc_has_perm(ipcp, av);
} }
static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
{
struct ipc_security_struct *isec = ipcp->security;
return selinux_getsecurity(isec->sid, buffer, size);
}
/* module stacking operations */ /* module stacking operations */
static int selinux_register_security (const char *name, struct security_operations *ops) static int selinux_register_security (const char *name, struct security_operations *ops)
{ {
...@@ -4095,8 +4100,7 @@ static int selinux_getprocattr(struct task_struct *p, ...@@ -4095,8 +4100,7 @@ static int selinux_getprocattr(struct task_struct *p,
char *name, void *value, size_t size) char *name, void *value, size_t size)
{ {
struct task_security_struct *tsec; struct task_security_struct *tsec;
u32 sid, len; u32 sid;
char *context;
int error; int error;
if (current != p) { if (current != p) {
...@@ -4105,9 +4109,6 @@ static int selinux_getprocattr(struct task_struct *p, ...@@ -4105,9 +4109,6 @@ static int selinux_getprocattr(struct task_struct *p,
return error; return error;
} }
if (!size)
return -ERANGE;
tsec = p->security; tsec = p->security;
if (!strcmp(name, "current")) if (!strcmp(name, "current"))
...@@ -4124,16 +4125,7 @@ static int selinux_getprocattr(struct task_struct *p, ...@@ -4124,16 +4125,7 @@ static int selinux_getprocattr(struct task_struct *p,
if (!sid) if (!sid)
return 0; return 0;
error = security_sid_to_context(sid, &context, &len); return selinux_getsecurity(sid, value, size);
if (error)
return error;
if (len > size) {
kfree(context);
return -ERANGE;
}
memcpy(value, context, len);
kfree(context);
return len;
} }
static int selinux_setprocattr(struct task_struct *p, static int selinux_setprocattr(struct task_struct *p,
...@@ -4291,6 +4283,7 @@ static struct security_operations selinux_ops = { ...@@ -4291,6 +4283,7 @@ static struct security_operations selinux_ops = {
.inode_getxattr = selinux_inode_getxattr, .inode_getxattr = selinux_inode_getxattr,
.inode_listxattr = selinux_inode_listxattr, .inode_listxattr = selinux_inode_listxattr,
.inode_removexattr = selinux_inode_removexattr, .inode_removexattr = selinux_inode_removexattr,
.inode_xattr_getsuffix = selinux_inode_xattr_getsuffix,
.inode_getsecurity = selinux_inode_getsecurity, .inode_getsecurity = selinux_inode_getsecurity,
.inode_setsecurity = selinux_inode_setsecurity, .inode_setsecurity = selinux_inode_setsecurity,
.inode_listsecurity = selinux_inode_listsecurity, .inode_listsecurity = selinux_inode_listsecurity,
...@@ -4328,6 +4321,7 @@ static struct security_operations selinux_ops = { ...@@ -4328,6 +4321,7 @@ static struct security_operations selinux_ops = {
.task_to_inode = selinux_task_to_inode, .task_to_inode = selinux_task_to_inode,
.ipc_permission = selinux_ipc_permission, .ipc_permission = selinux_ipc_permission,
.ipc_getsecurity = selinux_ipc_getsecurity,
.msg_msg_alloc_security = selinux_msg_msg_alloc_security, .msg_msg_alloc_security = selinux_msg_msg_alloc_security,
.msg_msg_free_security = selinux_msg_msg_free_security, .msg_msg_free_security = selinux_msg_msg_free_security,
......
...@@ -106,6 +106,9 @@ static struct nlmsg_perm nlmsg_audit_perms[] = ...@@ -106,6 +106,9 @@ static struct nlmsg_perm nlmsg_audit_perms[] =
{ AUDIT_LIST, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV }, { AUDIT_LIST, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV },
{ AUDIT_ADD, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, { AUDIT_ADD, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
{ AUDIT_DEL, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, { AUDIT_DEL, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
{ AUDIT_LIST_RULES, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV },
{ AUDIT_ADD_RULE, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
{ AUDIT_DEL_RULE, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
{ AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY }, { AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY },
{ AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ }, { AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ },
}; };
...@@ -152,8 +155,10 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) ...@@ -152,8 +155,10 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
break; break;
case SECCLASS_NETLINK_AUDIT_SOCKET: case SECCLASS_NETLINK_AUDIT_SOCKET:
if (nlmsg_type >= AUDIT_FIRST_USER_MSG && if ((nlmsg_type >= AUDIT_FIRST_USER_MSG &&
nlmsg_type <= AUDIT_LAST_USER_MSG) { nlmsg_type <= AUDIT_LAST_USER_MSG) ||
(nlmsg_type >= AUDIT_FIRST_USER_MSG2 &&
nlmsg_type <= AUDIT_LAST_USER_MSG2)) {
*perm = NETLINK_AUDIT_SOCKET__NLMSG_RELAY; *perm = NETLINK_AUDIT_SOCKET__NLMSG_RELAY;
} else { } else {
err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms, err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms,
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/major.h> #include <linux/major.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/audit.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
...@@ -127,6 +128,10 @@ static ssize_t sel_write_enforce(struct file * file, const char __user * buf, ...@@ -127,6 +128,10 @@ static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
length = task_has_security(current, SECURITY__SETENFORCE); length = task_has_security(current, SECURITY__SETENFORCE);
if (length) if (length)
goto out; goto out;
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
"enforcing=%d old_enforcing=%d auid=%u", new_value,
selinux_enforcing,
audit_get_loginuid(current->audit_context));
selinux_enforcing = new_value; selinux_enforcing = new_value;
if (selinux_enforcing) if (selinux_enforcing)
avc_ss_reset(0); avc_ss_reset(0);
...@@ -177,6 +182,9 @@ static ssize_t sel_write_disable(struct file * file, const char __user * buf, ...@@ -177,6 +182,9 @@ static ssize_t sel_write_disable(struct file * file, const char __user * buf,
length = selinux_disable(); length = selinux_disable();
if (length < 0) if (length < 0)
goto out; goto out;
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
"selinux=0 auid=%u",
audit_get_loginuid(current->audit_context));
} }
length = count; length = count;
...@@ -262,6 +270,9 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf, ...@@ -262,6 +270,9 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
length = ret; length = ret;
else else
length = count; length = count;
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
"policy loaded auid=%u",
audit_get_loginuid(current->audit_context));
out: out:
mutex_unlock(&sel_mutex); mutex_unlock(&sel_mutex);
vfree(data); vfree(data);
......
...@@ -1759,19 +1759,22 @@ int security_set_bools(int len, int *values) ...@@ -1759,19 +1759,22 @@ int security_set_bools(int len, int *values)
goto out; goto out;
} }
printk(KERN_INFO "security: committed booleans { ");
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (!!values[i] != policydb.bool_val_to_struct[i]->state) {
audit_log(current->audit_context, GFP_ATOMIC,
AUDIT_MAC_CONFIG_CHANGE,
"bool=%s val=%d old_val=%d auid=%u",
policydb.p_bool_val_to_name[i],
!!values[i],
policydb.bool_val_to_struct[i]->state,
audit_get_loginuid(current->audit_context));
}
if (values[i]) { if (values[i]) {
policydb.bool_val_to_struct[i]->state = 1; policydb.bool_val_to_struct[i]->state = 1;
} else { } else {
policydb.bool_val_to_struct[i]->state = 0; policydb.bool_val_to_struct[i]->state = 0;
} }
if (i != 0)
printk(", ");
printk("%s:%d", policydb.p_bool_val_to_name[i],
policydb.bool_val_to_struct[i]->state);
} }
printk(" }\n");
for (cur = policydb.cond_list; cur != NULL; cur = cur->next) { for (cur = policydb.cond_list; cur != NULL; cur = cur->next) {
rc = evaluate_cond_node(&policydb, cur); rc = evaluate_cond_node(&policydb, cur);
......
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