Commit 75c4f219 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] SELinux: Extend and revise calls to secondary module

From: Stephen Smalley <sds@epoch.ncsc.mil>

This patch extends the set of calls to the secondary security module by
SELinux as well as revising a few existing calls to support other security
modules and to more cleanly stack with the capability module.  Please
apply.
Signed-off-by: default avatarStephen Smalley <sds@epoch.ncsc.mil>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d2c40dc0
...@@ -1389,11 +1389,11 @@ static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effect ...@@ -1389,11 +1389,11 @@ static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effect
{ {
int error; int error;
error = task_has_perm(current, target, PROCESS__SETCAP); error = secondary_ops->capset_check(target, effective, inheritable, permitted);
if (error) if (error)
return error; return error;
return secondary_ops->capset_check(target, effective, inheritable, permitted); return task_has_perm(current, target, PROCESS__SETCAP);
} }
static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective, static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective,
...@@ -1427,6 +1427,10 @@ static int selinux_sysctl(ctl_table *table, int op) ...@@ -1427,6 +1427,10 @@ static int selinux_sysctl(ctl_table *table, int op)
u32 tsid; u32 tsid;
int rc; int rc;
rc = secondary_ops->sysctl(table, op);
if (rc)
return rc;
tsec = current->security; tsec = current->security;
rc = selinux_proc_get_sid(table->de, (op == 001) ? rc = selinux_proc_get_sid(table->de, (op == 001) ?
...@@ -1690,7 +1694,7 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm) ...@@ -1690,7 +1694,7 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm)
static int selinux_bprm_check_security (struct linux_binprm *bprm) static int selinux_bprm_check_security (struct linux_binprm *bprm)
{ {
return 0; return secondary_ops->bprm_check_security(bprm);
} }
...@@ -1708,12 +1712,7 @@ static int selinux_bprm_secureexec (struct linux_binprm *bprm) ...@@ -1708,12 +1712,7 @@ static int selinux_bprm_secureexec (struct linux_binprm *bprm)
PROCESS__NOATSECURE, NULL, NULL); PROCESS__NOATSECURE, NULL, NULL);
} }
/* Note that we must include the legacy uid/gid test below return (atsecure || secondary_ops->bprm_secureexec(bprm));
to retain it, as the new userland will simply use the
value passed by AT_SECURE to decide whether to enable
secure mode. */
return ( atsecure || current->euid != current->uid ||
current->egid != current->gid);
} }
static void selinux_bprm_free_security(struct linux_binprm *bprm) static void selinux_bprm_free_security(struct linux_binprm *bprm)
...@@ -2058,6 +2057,12 @@ static int selinux_mount(char * dev_name, ...@@ -2058,6 +2057,12 @@ static int selinux_mount(char * dev_name,
unsigned long flags, unsigned long flags,
void * data) void * data)
{ {
int rc;
rc = secondary_ops->sb_mount(dev_name, nd, type, flags, data);
if (rc)
return rc;
if (flags & MS_REMOUNT) if (flags & MS_REMOUNT)
return superblock_has_perm(current, nd->mnt->mnt_sb, return superblock_has_perm(current, nd->mnt->mnt_sb,
FILESYSTEM__REMOUNT, NULL); FILESYSTEM__REMOUNT, NULL);
...@@ -2068,6 +2073,12 @@ static int selinux_mount(char * dev_name, ...@@ -2068,6 +2073,12 @@ static int selinux_mount(char * dev_name,
static int selinux_umount(struct vfsmount *mnt, int flags) static int selinux_umount(struct vfsmount *mnt, int flags)
{ {
int rc;
rc = secondary_ops->sb_umount(mnt, flags);
if (rc)
return rc;
return superblock_has_perm(current,mnt->mnt_sb, return superblock_has_perm(current,mnt->mnt_sb,
FILESYSTEM__UNMOUNT,NULL); FILESYSTEM__UNMOUNT,NULL);
} }
...@@ -2111,6 +2122,11 @@ static void selinux_inode_post_link(struct dentry *old_dentry, struct inode *ino ...@@ -2111,6 +2122,11 @@ static void selinux_inode_post_link(struct dentry *old_dentry, struct inode *ino
static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry) static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
{ {
int rc;
rc = secondary_ops->inode_unlink(dir, dentry);
if (rc)
return rc;
return may_link(dir, dentry, MAY_UNLINK); return may_link(dir, dentry, MAY_UNLINK);
} }
...@@ -2141,6 +2157,12 @@ static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -2141,6 +2157,12 @@ static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
{ {
int rc;
rc = secondary_ops->inode_mknod(dir, dentry, mode, dev);
if (rc)
return rc;
return may_create(dir, dentry, inode_mode_to_security_class(mode)); return may_create(dir, dentry, inode_mode_to_security_class(mode));
} }
...@@ -2179,6 +2201,12 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na ...@@ -2179,6 +2201,12 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
static int selinux_inode_permission(struct inode *inode, int mask, static int selinux_inode_permission(struct inode *inode, int mask,
struct nameidata *nd) struct nameidata *nd)
{ {
int rc;
rc = secondary_ops->inode_permission(inode, mask, nd);
if (rc)
return rc;
if (!mask) { if (!mask) {
/* No permission to check. Existence test. */ /* No permission to check. Existence test. */
return 0; return 0;
...@@ -2190,6 +2218,12 @@ static int selinux_inode_permission(struct inode *inode, int mask, ...@@ -2190,6 +2218,12 @@ static int selinux_inode_permission(struct inode *inode, int mask,
static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
{ {
int rc;
rc = secondary_ops->inode_setattr(dentry, iattr);
if (rc)
return rc;
if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
ATTR_ATIME_SET | ATTR_MTIME_SET)) ATTR_ATIME_SET | ATTR_MTIME_SET))
return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
...@@ -2456,6 +2490,11 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, ...@@ -2456,6 +2490,11 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
static int selinux_file_mmap(struct file *file, unsigned long prot, unsigned long flags) static int selinux_file_mmap(struct file *file, unsigned long prot, unsigned long flags)
{ {
u32 av; u32 av;
int rc;
rc = secondary_ops->file_mmap(file, prot, flags);
if (rc)
return rc;
if (file) { if (file) {
/* read access is always possible with a mapping */ /* read access is always possible with a mapping */
...@@ -2476,6 +2515,12 @@ static int selinux_file_mmap(struct file *file, unsigned long prot, unsigned lon ...@@ -2476,6 +2515,12 @@ static int selinux_file_mmap(struct file *file, unsigned long prot, unsigned lon
static int selinux_file_mprotect(struct vm_area_struct *vma, static int selinux_file_mprotect(struct vm_area_struct *vma,
unsigned long prot) unsigned long prot)
{ {
int rc;
rc = secondary_ops->file_mprotect(vma, prot);
if (rc)
return rc;
return selinux_file_mmap(vma->vm_file, prot, vma->vm_flags); return selinux_file_mmap(vma->vm_file, prot, vma->vm_flags);
} }
...@@ -2573,6 +2618,12 @@ static int selinux_file_receive(struct file *file) ...@@ -2573,6 +2618,12 @@ static int selinux_file_receive(struct file *file)
static int selinux_task_create(unsigned long clone_flags) static int selinux_task_create(unsigned long clone_flags)
{ {
int rc;
rc = secondary_ops->task_create(clone_flags);
if (rc)
return rc;
return task_has_perm(current, current, PROCESS__FORK); return task_has_perm(current, current, PROCESS__FORK);
} }
...@@ -2648,12 +2699,23 @@ static int selinux_task_setgroups(struct group_info *group_info) ...@@ -2648,12 +2699,23 @@ static int selinux_task_setgroups(struct group_info *group_info)
static int selinux_task_setnice(struct task_struct *p, int nice) static int selinux_task_setnice(struct task_struct *p, int nice)
{ {
int rc;
rc = secondary_ops->task_setnice(p, nice);
if (rc)
return rc;
return task_has_perm(current,p, PROCESS__SETSCHED); return task_has_perm(current,p, PROCESS__SETSCHED);
} }
static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
{ {
struct rlimit *old_rlim = current->rlim + resource; struct rlimit *old_rlim = current->rlim + resource;
int rc;
rc = secondary_ops->task_setrlimit(resource, new_rlim);
if (rc)
return rc;
/* Control the ability to change the hard limit (whether /* Control the ability to change the hard limit (whether
lowering or raising it), so that the hard limit can lowering or raising it), so that the hard limit can
...@@ -2688,6 +2750,11 @@ static int selinux_task_getscheduler(struct task_struct *p) ...@@ -2688,6 +2750,11 @@ static int selinux_task_getscheduler(struct task_struct *p)
static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig) static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig)
{ {
u32 perm; u32 perm;
int rc;
rc = secondary_ops->task_kill(p, info, sig);
if (rc)
return rc;
if (info && ((unsigned long)info == 1 || if (info && ((unsigned long)info == 1 ||
(unsigned long)info == 2 || SI_FROMKERNEL(info))) (unsigned long)info == 2 || SI_FROMKERNEL(info)))
...@@ -3129,6 +3196,10 @@ static int selinux_socket_unix_stream_connect(struct socket *sock, ...@@ -3129,6 +3196,10 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
struct avc_audit_data ad; struct avc_audit_data ad;
int err; int err;
err = secondary_ops->unix_stream_connect(sock, other, newsk);
if (err)
return err;
isec = SOCK_INODE(sock)->i_security; isec = SOCK_INODE(sock)->i_security;
other_isec = SOCK_INODE(other)->i_security; other_isec = SOCK_INODE(other)->i_security;
...@@ -3847,6 +3918,11 @@ static int selinux_shm_shmat(struct shmid_kernel *shp, ...@@ -3847,6 +3918,11 @@ static int selinux_shm_shmat(struct shmid_kernel *shp,
char __user *shmaddr, int shmflg) char __user *shmaddr, int shmflg)
{ {
u32 perms; u32 perms;
int rc;
rc = secondary_ops->shm_shmat(shp, shmaddr, shmflg);
if (rc)
return rc;
if (shmflg & SHM_RDONLY) if (shmflg & SHM_RDONLY)
perms = SHM__READ; perms = SHM__READ;
......
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