Re: [PATCH 2/2] selinux: implement mmap on /selinux/policy

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 2010-07-26 at 15:34 -0400, Eric Paris wrote:
> /selinux/policy allows a user to copy the policy back out of the kernel.
> This patch allows userspace to actually mmap that file and use it directly.

# checkpolicy -b /selinux/policy
checkpolicy:  loading policy configuration from /selinux/policy
Can't map '/selinux/policy':  Invalid argument

# strace checkpolicy -b /selinux/policy
...
open("/selinux/policy", O_RDONLY)       = 3
fstat(3, {st_mode=S_IFREG|0400, st_size=5720516, ...}) = 0
mmap(NULL, 5720516, PROT_READ|PROT_WRITE, MAP_PRIVATE, 3, 0) = -1 EINVAL
(Invalid argument)

> 
> Signed-off-by: Eric Paris <eparis@xxxxxxxxxx>
> ---
> 
>  security/selinux/selinuxfs.c |   44 ++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 44 insertions(+), 0 deletions(-)
> 
> diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
> index e0c2bcf..864a74e 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -68,6 +68,8 @@ static int *bool_pending_values;
>  static struct dentry *class_dir;
>  static unsigned long last_class_ino;
>  
> +static char policy_opened;
> +
>  /* global data for policy capabilities */
>  static struct dentry *policycap_dir;
>  
> @@ -315,11 +317,23 @@ static int sel_open_policy(struct inode *inode, struct file *filp)
>  	if (rc)
>  		goto err;
>  
> +	if (policy_opened) {
> +		mutex_unlock(&sel_mutex);
> +		return -EBUSY;
> +	}
> +	policy_opened = 1;
> +
>  	rc = -ENOMEM;
>  	plm = kzalloc(sizeof(*plm), GFP_KERNEL);
>  	if (!plm)
>  		goto err;
>  
> +	if (i_size_read(inode) != security_policydb_len()) {
> +		mutex_lock(&inode->i_mutex);
> +		i_size_write(inode, security_policydb_len());
> +		mutex_unlock(&inode->i_mutex);
> +	}
> +
>  	rc = security_read_policy(&plm->data, &plm->len);
>  	if (rc)
>  		goto err;
> @@ -344,6 +358,8 @@ static int sel_release_policy(struct inode *inode, struct file *filp)
>  
>  	BUG_ON(!plm);
>  
> +	policy_opened = 0;
> +
>  	vfree(plm->data);
>  	kfree(plm);
>  
> @@ -381,9 +397,37 @@ out:
>  	return ret;
>  }
>  
> +static int sel_mmap_policy(struct file *filp, struct vm_area_struct *vma)
> +{
> +	int ret;
> +	long length = vma->vm_end - vma->vm_start;
> +	unsigned long start = vma->vm_start;
> +	struct policy_load_memory *plm = filp->private_data;
> +	char *pos = plm->data;
> +	unsigned long pfn;
> +
> +	if (vma->vm_pgoff != 0)
> +		return -EIO;
> +
> +	if (length > roundup(plm->len, PAGE_SIZE))
> +		return -EIO;
> +
> +	while (length > 0) {
> +		pfn = vmalloc_to_pfn(pos);
> +		ret = remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED);
> +		if (ret)
> +			return ret;
> +		start += PAGE_SIZE;
> +		pos += PAGE_SIZE;
> +		length -= PAGE_SIZE;
> +	}
> +	return 0;
> +}
> +
>  static const struct file_operations sel_policy_ops = {
>  	.open		= sel_open_policy,
>  	.read		= sel_read_policy,
> +	.mmap		= sel_mmap_policy,
>  	.release	= sel_release_policy,
>  };
>  

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.


[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux