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

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

 



On Tue, 2010-07-27 at 14:36 -0400, Stephen Smalley wrote:
> 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.
> > 
> > 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);
> > +	}
> 
> What exactly are we doing here?
> Do we truly want to limit /selinux/policy to one process at a time?
> Why is that necessary?

My fear was:

Process A			Process B
------------------------	-------------------------
open("/selinux/policy");
  plm->data = p1
  plm->len = l1
  i_size = l1
				load_policy
				open("/selinux/policy");
				  plm->data = p2;
				  plm->len = l2;
				  i_size = l2;
				stat("/selinux/policy");
				  we get i_size=l2
stat("/selinux/policy");
  we get i_size=l2  WHOOPS.

> >  	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;
> > +}
> 
> I'm not overly familiar with this area - can you point to an
> example .mmap handler that you used as the basis for your
> implementation?

I basically stole from:
http://www.scs.ch/~frey/linux/memorymap.html
http://www.scs.ch/~frey/linux/mmap.example.tar

Although seeing as how remap_pfn_range() only works for MAP_SHARED I'm
reading http://www.xml.com/ldd/chapter/book/ch13.html as a hopefully
better way to do it.


--
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