mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
selinux: allow multiple opens of /sys/fs/selinux/policy
Currently there can only be a single open of /sys/fs/selinux/policy at any time. This allows any process to block any other process from reading the kernel policy. The original motivation seems to have been a mix of preventing an inconsistent view of the policy size and preventing userspace from allocating kernel memory without bound, but this is arguably equally bad. Eliminate the policy_opened flag and shrink the critical section that the policy mutex is held. While we are making changes here, drop a couple of extraneous BUG_ONs. Cc: stable@vger.kernel.org Link: https://lore.kernel.org/selinux/20100726193414.19538.64028.stgit@paris.rdu.redhat.com/ Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
parent
ad1ac3d740
commit
a02cd68055
|
|
@ -76,7 +76,6 @@ struct selinux_fs_info {
|
|||
int *bool_pending_values;
|
||||
struct dentry *class_dir;
|
||||
unsigned long last_class_ino;
|
||||
bool policy_opened;
|
||||
unsigned long last_ino;
|
||||
struct super_block *sb;
|
||||
};
|
||||
|
|
@ -340,44 +339,31 @@ struct policy_load_memory {
|
|||
|
||||
static int sel_open_policy(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct selinux_fs_info *fsi = inode->i_sb->s_fs_info;
|
||||
struct policy_load_memory *plm = NULL;
|
||||
int rc;
|
||||
|
||||
BUG_ON(filp->private_data);
|
||||
|
||||
mutex_lock(&selinux_state.policy_mutex);
|
||||
|
||||
rc = avc_has_perm(current_sid(), SECINITSID_SECURITY,
|
||||
SECCLASS_SECURITY, SECURITY__READ_POLICY, NULL);
|
||||
if (rc)
|
||||
goto err;
|
||||
return rc;
|
||||
|
||||
rc = -EBUSY;
|
||||
if (fsi->policy_opened)
|
||||
goto err;
|
||||
|
||||
rc = -ENOMEM;
|
||||
plm = kzalloc_obj(*plm);
|
||||
if (!plm)
|
||||
goto err;
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&selinux_state.policy_mutex);
|
||||
rc = security_read_policy(&plm->data, &plm->len);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
if ((size_t)i_size_read(inode) != plm->len) {
|
||||
inode_lock(inode);
|
||||
i_size_write(inode, plm->len);
|
||||
inode_unlock(inode);
|
||||
}
|
||||
|
||||
fsi->policy_opened = 1;
|
||||
mutex_unlock(&selinux_state.policy_mutex);
|
||||
|
||||
filp->private_data = plm;
|
||||
|
||||
mutex_unlock(&selinux_state.policy_mutex);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
mutex_unlock(&selinux_state.policy_mutex);
|
||||
|
|
@ -390,13 +376,8 @@ static int sel_open_policy(struct inode *inode, struct file *filp)
|
|||
|
||||
static int sel_release_policy(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct selinux_fs_info *fsi = inode->i_sb->s_fs_info;
|
||||
struct policy_load_memory *plm = filp->private_data;
|
||||
|
||||
BUG_ON(!plm);
|
||||
|
||||
fsi->policy_opened = 0;
|
||||
|
||||
vfree(plm->data);
|
||||
kfree(plm);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user