RE: [PATCH] libselinux: disable refcounting in the userspace AVC

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

 



> From: Stephen Smalley [mailto:sds@xxxxxxxxxxxxx]
> 
> On Tue, 2009-09-01 at 23:35 -0400, Eamon Walsh wrote:
> > The userspace AVC currently has refcounted SID's.  This patch strips
> out
> > the refcounting under the following justifications:
> >
> > 1.  Managing the refcounts by calling sidput() and sidget() as
> > appropriate is a difficult and bug-prone task for users of the
> library.
> >
> > 2.  The userspace AVC doesn't currently make use of the refcounts to
> > reclaim unused SID's unless avc_cleanup() is explicitly called.
> >
> > 3.  The kernel itself no longer uses refcounting for it's own SID's.
> 
> Just to clarify on this point:  Early on we had discussed introducing
> refcounting of kernel SIDs to enable reclaiming unused ones, but this
> became less important once the user/kernel interface was converted
from
> passing SIDs to passing security contexts.  In that case we were
> dealing
> with a global (wrt a system) resource and kernel memory, whereas in
the
> userspace AVC we are only dealing with a per-object-manager SID table
> and the application's virtual memory.
> 

So is the purpose of the patch just to remove unnecessary complication
in the userspace sidtab? Will this affect multithreaded applications
that share a sidtab? 

IIRC sepostgres reimplemented its sidtab and avc because our current one
wasn't very friendly to multithread/multiprocess object managers.

> > The implication of this change is that SID's (basically malloc'ed
> copies
> > of security contexts) will persist in the AVC's SID table until the
> next
> > call to avc_destroy().  This presents the potential for increased
> memory
> > usage, but in practice I don't believe this will be an issue.  ABI
> > compatibility is preserved: the avc_cleanup(), sidput(), and
sidget()
> > calls are changed to no-ops.
> >
> > Signed-off-by: Eamon Walsh <ewalsh@xxxxxxxxxxxxx>
> 
> Acked-by:  Stephen Smalley <sds@xxxxxxxxxxxxx>
> 
> > ---
> >
> >   avc.c          |  122
+++++++--------------------------------------
> ------------
> >   avc_internal.h |   11 -----
> >   avc_sidtab.c   |   42 -------------------
> >   avc_sidtab.h   |    2
> >   4 files changed, 16 insertions(+), 161 deletions(-)
> >
> >
> > diff --git a/libselinux/src/avc.c b/libselinux/src/avc.c
> > index f0e2d33..1c62fa3 100644
> > --- a/libselinux/src/avc.c
> > +++ b/libselinux/src/avc.c
> > @@ -71,8 +71,6 @@ int avc_context_to_sid_raw(security_context_t ctx,
> security_id_t * sid)
> >   	int rc;
> >   	avc_get_lock(avc_lock);
> >   	rc = sidtab_context_to_sid(&avc_sidtab, ctx, sid);
> > -	if (!rc)
> > -		(*sid)->refcnt++;
> >   	avc_release_lock(avc_lock);
> >   	return rc;
> >   }
> > @@ -97,13 +95,8 @@ int avc_sid_to_context_raw(security_id_t sid,
> security_context_t * ctx)
> >   	int rc;
> >   	*ctx = NULL;
> >   	avc_get_lock(avc_lock);
> > -	if (sid->refcnt>  0) {
> > -		*ctx = strdup(sid->ctx);	/* caller must free via
> freecon */
> > -		rc = *ctx ? 0 : -1;
> > -	} else {
> > -		errno = EINVAL;	/* bad reference count */
> > -		rc = -1;
> > -	}
> > +	*ctx = strdup(sid->ctx);	/* caller must free via freecon
*/
> > +	rc = *ctx ? 0 : -1;
> >   	avc_release_lock(avc_lock);
> >   	return rc;
> >   }
> > @@ -123,24 +116,14 @@ int avc_sid_to_context(security_id_t sid,
> security_context_t * ctx)
> >   	return ret;
> >   }
> >
> > -int sidget(security_id_t sid)
> > +int sidget(security_id_t sid __attribute__((unused)))
> >   {
> > -	int rc;
> > -	avc_get_lock(avc_lock);
> > -	rc = sid_inc_refcnt(sid);
> > -	avc_release_lock(avc_lock);
> > -	return rc;
> > +	return 1;
> >   }
> >
> > -int sidput(security_id_t sid)
> > +int sidput(security_id_t sid __attribute__((unused)))
> >   {
> > -	int rc;
> > -	if (!sid)
> > -	    return 0;
> > -	avc_get_lock(avc_lock);
> > -	rc = sid_dec_refcnt(sid);
> > -	avc_release_lock(avc_lock);
> > -	return rc;
> > +	return 1;
> >   }
> >
> >   int avc_get_initial_sid(const char * name, security_id_t * sid)
> > @@ -505,57 +488,8 @@ static int avc_insert(security_id_t ssid,
> security_id_t tsid,
> >   	return rc;
> >   }
> >
> > -/**
> > - * avc_remove - Remove AVC and sidtab entries for SID.
> > - * @sid: security identifier to be removed
> > - *
> > - * Remove all AVC entries containing @sid as source, target, or
> > - * create_sid, and remove @sid from the SID table.
> > - * Free the memory allocated for the structure corresponding
> > - * to @sid.  After this function has been called, @sid must
> > - * not be used until another call to avc_context_to_sid() has
> > - * been made for this SID.
> > - */
> > -static void avc_remove(security_id_t sid)
> > -{
> > -	struct avc_node *prev, *cur, *tmp;
> > -	int i;
> > -
> > -	for (i = 0; i<  AVC_CACHE_SLOTS; i++) {
> > -		cur = avc_cache.slots[i];
> > -		prev = NULL;
> > -		while (cur) {
> > -			if (sid == cur->ae.ssid || sid == cur->ae.tsid
||
> > -			    sid == cur->ae.create_sid) {
> > -				if (prev)
> > -					prev->next = cur->next;
> > -				else
> > -					avc_cache.slots[i] = cur->next;
> > -				tmp = cur;
> > -				cur = cur->next;
> > -				avc_clear_avc_entry(&tmp->ae);
> > -				tmp->next = avc_node_freelist;
> > -				avc_node_freelist = tmp;
> > -				avc_cache.active_nodes--;
> > -			} else {
> > -				prev = cur;
> > -				cur = cur->next;
> > -			}
> > -		}
> > -	}
> > -	sidtab_remove(&avc_sidtab, sid);
> > -}
> > -
> >   void avc_cleanup(void)
> >   {
> > -	security_id_t sid;
> > -
> > -	avc_get_lock(avc_lock);
> > -
> > -	while (NULL != (sid = sidtab_claim_sid(&avc_sidtab)))
> > -		avc_remove(sid);
> > -
> > -	avc_release_lock(avc_lock);
> >   }
> >
> >   hidden_def(avc_cleanup)
> > @@ -745,15 +679,8 @@ static void avc_dump_query(security_id_t ssid,
> security_id_t tsid,
> >   {
> >   	avc_get_lock(avc_lock);
> >
> > -	if (ssid->refcnt>  0)
> > -		log_append(avc_audit_buf, "scontext=%s", ssid->ctx);
> > -	else
> > -		log_append(avc_audit_buf, "ssid=%p", ssid);
> > -
> > -	if (tsid->refcnt>  0)
> > -		log_append(avc_audit_buf, " tcontext=%s", tsid->ctx);
> > -	else
> > -		log_append(avc_audit_buf, " tsid=%p", tsid);
> > +	log_append(avc_audit_buf, "scontext=%s tcontext=%s",
> > +		   ssid->ctx, tsid->ctx);
> >
> >   	avc_release_lock(avc_lock);
> >   	log_append(avc_audit_buf, " tclass=%s",
> > @@ -844,11 +771,6 @@ int avc_has_perm_noaudit(security_id_t ssid,
> >   		avc_cache_stats_incr(entry_misses);
> >   		rc = avc_lookup(ssid, tsid, tclass, requested, aeref);
> >   		if (rc) {
> > -			if ((ssid->refcnt<= 0) || (tsid->refcnt<= 0)) {
> > -				errno = EINVAL;
> > -				rc = -1;
> > -				goto out;
> > -			}
> >   			rc = security_compute_av_flags_raw(ssid->ctx,
tsid-
> >ctx,
> >   							   tclass,
requested,
> >   							&entry.avd);
> > @@ -911,11 +833,6 @@ int avc_compute_create(security_id_t ssid,
> security_id_t tsid,
> >   	avc_entry_ref_init(&aeref);
> >
> >   	avc_get_lock(avc_lock);
> > -	if (ssid->refcnt<= 0 || tsid->refcnt<= 0) {
> > -		errno = EINVAL;	/* bad reference count */
> > -		rc = -1;
> > -		goto out;
> > -	}
> >
> >   	/* check for a cached entry */
> >   	rc = avc_lookup(ssid, tsid, tclass, 0,&aeref);
> > @@ -950,8 +867,6 @@ int avc_compute_create(security_id_t ssid,
> security_id_t tsid,
> >
> >   	rc = 0;
> >   out:
> > -	if (*newsid)
> > -		(*newsid)->refcnt++;
> >   	avc_release_lock(avc_lock);
> >   	return rc;
> >   }
> > @@ -960,22 +875,15 @@ int avc_compute_member(security_id_t ssid,
> security_id_t tsid,
> >   		       security_class_t tclass, security_id_t *newsid)
> >   {
> >   	int rc;
> > +	security_context_t ctx = NULL;
> >   	*newsid = NULL;
> >   	avc_get_lock(avc_lock);
> > -	if (ssid->refcnt>  0&&  tsid->refcnt>  0) {
> > -		security_context_t ctx = NULL;
> > -		rc = security_compute_member_raw(ssid->ctx, tsid->ctx,
> tclass,
> > -						&ctx);
> > -		if (rc)
> > -			goto out;
> > -		rc = sidtab_context_to_sid(&avc_sidtab, ctx, newsid);
> > -		if (!rc)
> > -			(*newsid)->refcnt++;
> > -		freecon(ctx);
> > -	} else {
> > -		errno = EINVAL;	/* bad reference count */
> > -		rc = -1;
> > -	}
> > +
> > +	rc = security_compute_member_raw(ssid->ctx, tsid->ctx,
> tclass,&ctx);
> > +	if (rc)
> > +		goto out;
> > +	rc = sidtab_context_to_sid(&avc_sidtab, ctx, newsid);
> > +	freecon(ctx);
> >   out:
> >   	avc_release_lock(avc_lock);
> >   	return rc;
> > diff --git a/libselinux/src/avc_internal.h
> b/libselinux/src/avc_internal.h
> > index e9e5772..53610e8 100644
> > --- a/libselinux/src/avc_internal.h
> > +++ b/libselinux/src/avc_internal.h
> > @@ -16,17 +16,6 @@
> >   #include "callbacks.h"
> >   #include "dso.h"
> >
> > -/* SID reference counter manipulation */
> > -static inline int sid_inc_refcnt(security_id_t sid)
> > -{
> > -	return sid->refcnt = (sid->refcnt>  0) ? sid->refcnt + 1 : 0;
> > -}
> > -
> > -static inline int sid_dec_refcnt(security_id_t sid)
> > -{
> > -	return sid->refcnt = (sid->refcnt>  0) ? sid->refcnt - 1 : 0;
> > -}
> > -
> >   /* callback pointers */
> >   extern void *(*avc_func_malloc) (size_t) hidden;
> >   extern void (*avc_func_free) (void *)hidden;
> > diff --git a/libselinux/src/avc_sidtab.c
> b/libselinux/src/avc_sidtab.c
> > index dab5c4e..3ca1d1f 100644
> > --- a/libselinux/src/avc_sidtab.c
> > +++ b/libselinux/src/avc_sidtab.c
> > @@ -67,53 +67,13 @@ int sidtab_insert(struct sidtab *s,
> security_context_t ctx)
> >   	hvalue = sidtab_hash(newctx);
> >   	newnode->next = s->htable[hvalue];
> >   	newnode->sid_s.ctx = newctx;
> > -	newnode->sid_s.refcnt = 0;	/* caller should increment */
> > +	newnode->sid_s.refcnt = 1;	/* unused */
> >   	s->htable[hvalue] = newnode;
> >   	s->nel++;
> >         out:
> >   	return rc;
> >   }
> >
> > -void sidtab_remove(struct sidtab *s, security_id_t sid)
> > -{
> > -	int hvalue;
> > -	struct sidtab_node *cur, *prev;
> > -
> > -	hvalue = sidtab_hash(sid->ctx);
> > -	cur = s->htable[hvalue];
> > -	prev = NULL;
> > -	while (cur) {
> > -		if (sid ==&cur->sid_s) {
> > -			if (prev)
> > -				prev->next = cur->next;
> > -			else
> > -				s->htable[hvalue] = cur->next;
> > -			avc_free(cur);
> > -			s->nel--;
> > -			return;
> > -		} else {
> > -			prev = cur;
> > -			cur = cur->next;
> > -		}
> > -	}
> > -}
> > -
> > -security_id_t sidtab_claim_sid(struct sidtab *s)
> > -{
> > -	int i;
> > -	struct sidtab_node *cur;
> > -
> > -	for (i = 0; i<  SIDTAB_SIZE; i++) {
> > -		cur = s->htable[i];
> > -		while (cur) {
> > -			if (!cur->sid_s.refcnt)
> > -				return&cur->sid_s;
> > -			cur = cur->next;
> > -		}
> > -	}
> > -	return NULL;
> > -}
> > -
> >   int
> >   sidtab_context_to_sid(struct sidtab *s,
> >   		      security_context_t ctx, security_id_t * sid)
> > diff --git a/libselinux/src/avc_sidtab.h
> b/libselinux/src/avc_sidtab.h
> > index 620a335..29b5d8b 100644
> > --- a/libselinux/src/avc_sidtab.h
> > +++ b/libselinux/src/avc_sidtab.h
> > @@ -26,8 +26,6 @@ struct sidtab {
> >
> >   int sidtab_init(struct sidtab *s) hidden;
> >   int sidtab_insert(struct sidtab *s, security_context_t ctx)
hidden;
> > -void sidtab_remove(struct sidtab *s, security_id_t sid) hidden;
> > -security_id_t sidtab_claim_sid(struct sidtab *s) hidden;
> >
> >   int sidtab_context_to_sid(struct sidtab *s,
> >   			  security_context_t ctx, security_id_t * sid)
> hidden;
> >
> >
> >
> --
> 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