[PATCH v2 4/5] selinux: Use pointer to switch policydb and sidtab

Stephen Smalley sds at tycho.nsa.gov
Thu Feb 8 15:10:41 UTC 2018


On Thu, 2018-02-08 at 08:16 +0100, peter enderborg wrote:
> On 01/30/2018 03:37 PM, Stephen Smalley wrote:
> > On Fri, 2018-01-26 at 15:32 +0100, peter.enderborg at sony.com wrote:
> > goto err;
> >  
> > -	rc = security_preserve_bools(newpolicydb);
> > +	rc = security_preserve_bools(&next_rcu->policydb);
> >  	if (rc) {
> >  		printk(KERN_ERR "SELinux:  unable to preserve
> > booleans\n");
> >  		goto err;
> > Most of this shouldn't need to be under the read lock.
> > 
> > > @@ -2189,7 +2194,7 @@ int security_load_policy(void *data, size_t
> > > len)
> > >  	 * in the new SID table.
> > >  	 */
> > >  	args.oldp = &crm->policydb;
> > > -	args.newp = newpolicydb;
> > > +	args.newp = &next_rcu->policydb;
> > >  	rc = sidtab_map(&newsidtab, convert_context, &args);
> > >  	if (rc) {
> > >  		printk(KERN_ERR "SELinux:  unable to convert the
> > > internal"
> > > @@ -2204,8 +2209,9 @@ int security_load_policy(void *data, size_t
> > > len)
> > >  
> > >  	/* Install the new policydb and SID table. */
> > >  	/* next */
> > > +	security_load_policycaps(&next_rcu->policydb);
> > 
> > This cannot be done outside of the write lock; it has to be atomic
> > with
> > the policy switch.
> 
> Can you please elaborate, does some else write the policydb without a
> lock?
> Is there any other data that is shared? I see this as a private until
> we switch the pointer.

security_load_policycaps() updates the selinux_policycap_* variables
from the policydb.  Those variables are used by the hooks to
enable/disable policy-specific functionality, like whether to check
open permission or assign finer-grained security classes to sockets. 
We need to atomically update those variables with the active policy;
otherwise, a hook may perform a permission check that wasn't supposed
to be enabled under the old policy against the old policy (yielding an
unexpected denial).  Everything done under the write lock currently is
there for a reason.

> > > +	read_unlock(&policy_rwlock);
> > >  	write_lock_irq(&policy_rwlock);
> > > -	memcpy(&next_rcu->policydb, newpolicydb, sizeof(struct
> > > policydb));
> > >  	sidtab_set(&next_rcu->sidtab, &newsidtab);
> > >  	security_load_policycaps(&next_rcu->policydb);
> > >  	oldmap = crm->current_mapping;
> > > @@ -2213,8 +2219,9 @@ int security_load_policy(void *data, size_t
> > > len)
> > >  	next_rcu->current_mapping_size = map_size;
> > >  
> > >  	seqno = ++latest_granting;
> > > -	write_unlock_irq(&policy_rwlock);
> > > +	old_rcu = crm;
> > >  	crm = next_rcu;
> > > +	write_unlock_irq(&policy_rwlock);
> > >  
> > >  	/* Free the old policydb and SID table. */
> > >  	policydb_destroy(oldpolicydb);
> > > @@ -2226,17 +2233,16 @@ int security_load_policy(void *data,
> > > size_t
> > > len)
> > >  	selinux_status_update_policyload(seqno);
> > >  	selinux_netlbl_cache_invalidate();
> > >  	selinux_xfrm_notify_policyload();
> > > +	kfree(oldpolicydb);
> > > +	kfree(old_rcu);
> > >  
> > >  	rc = 0;
> > >  	goto out;
> > > -
> > >  err:
> > >  	kfree(map);
> > >  	sidtab_destroy(&newsidtab);
> > > -	policydb_destroy(newpolicydb);
> > > -
> > > +	
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the Linux-security-module-archive mailing list