Skip to content

Commit

Permalink
SELinux: more careful use of avd in avc_has_perm_noaudit
Browse files Browse the repository at this point in the history
we are often needlessly jumping through hoops when it comes to avd
entries in avc_has_perm_noaudit and we have extra initialization and memcpy
which are just wasting performance.  Try to clean the function up a bit.

This patch resulted in a 13% drop in time spent in avc_has_perm_noaudit in my
oprofile sampling of a tbench benchmark.

Signed-off-by: Eric Paris <eparis@redhat.com>
Reviewed-by: Paul Moore <paul.moore@hp.com>
Acked-by:  Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
  • Loading branch information
Eric Paris authored and James Morris committed Feb 13, 2009
1 parent 906d27d commit 21193dc
Showing 1 changed file with 24 additions and 19 deletions.
43 changes: 24 additions & 19 deletions security/selinux/avc.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,12 @@ static struct avc_node *avc_alloc_node(void)
return node;
}

static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tclass, struct avc_entry *ae)
static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd)
{
node->ae.ssid = ssid;
node->ae.tsid = tsid;
node->ae.tclass = tclass;
memcpy(&node->ae.avd, &ae->avd, sizeof(node->ae.avd));
memcpy(&node->ae.avd, avd, sizeof(node->ae.avd));
}

static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
Expand Down Expand Up @@ -435,31 +435,31 @@ static int avc_latest_notif_update(int seqno, int is_insert)
* @ssid: source security identifier
* @tsid: target security identifier
* @tclass: target security class
* @ae: AVC entry
* @avd: resulting av decision
*
* Insert an AVC entry for the SID pair
* (@ssid, @tsid) and class @tclass.
* The access vectors and the sequence number are
* normally provided by the security server in
* response to a security_compute_av() call. If the
* sequence number @ae->avd.seqno is not less than the latest
* sequence number @avd->seqno is not less than the latest
* revocation notification, then the function copies
* the access vectors into a cache entry, returns
* avc_node inserted. Otherwise, this function returns NULL.
*/
static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct avc_entry *ae)
static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd)
{
struct avc_node *pos, *node = NULL;
int hvalue;
unsigned long flag;

if (avc_latest_notif_update(ae->avd.seqno, 1))
if (avc_latest_notif_update(avd->seqno, 1))
goto out;

node = avc_alloc_node();
if (node) {
hvalue = avc_hash(ssid, tsid, tclass);
avc_node_populate(node, ssid, tsid, tclass, ae);
avc_node_populate(node, ssid, tsid, tclass, avd);

spin_lock_irqsave(&avc_cache.slots_lock[hvalue], flag);
list_for_each_entry(pos, &avc_cache.slots[hvalue], list) {
Expand Down Expand Up @@ -772,7 +772,7 @@ static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass,
* Copy and replace original node.
*/

avc_node_populate(node, ssid, tsid, tclass, &orig->ae);
avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd);

switch (event) {
case AVC_CALLBACK_GRANT:
Expand Down Expand Up @@ -864,10 +864,10 @@ int avc_ss_reset(u32 seqno)
int avc_has_perm_noaudit(u32 ssid, u32 tsid,
u16 tclass, u32 requested,
unsigned flags,
struct av_decision *avd)
struct av_decision *in_avd)
{
struct avc_node *node;
struct avc_entry entry, *p_ae;
struct av_decision avd_entry, *avd;
int rc = 0;
u32 denied;

Expand All @@ -878,26 +878,31 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
node = avc_lookup(ssid, tsid, tclass, requested);
if (!node) {
rcu_read_unlock();
rc = security_compute_av(ssid, tsid, tclass, requested, &entry.avd);

if (in_avd)
avd = in_avd;
else
avd = &avd_entry;

rc = security_compute_av(ssid, tsid, tclass, requested, avd);
if (rc)
goto out;
rcu_read_lock();
node = avc_insert(ssid, tsid, tclass, &entry);
node = avc_insert(ssid, tsid, tclass, avd);
} else {
if (in_avd)
memcpy(in_avd, &node->ae.avd, sizeof(*in_avd));
avd = &node->ae.avd;
}

p_ae = node ? &node->ae : &entry;

if (avd)
memcpy(avd, &p_ae->avd, sizeof(*avd));

denied = requested & ~(p_ae->avd.allowed);
denied = requested & ~(avd->allowed);

if (denied) {
if (flags & AVC_STRICT)
rc = -EACCES;
else if (!selinux_enforcing || security_permissive_sid(ssid))
avc_update_node(AVC_CALLBACK_GRANT, requested, ssid,
tsid, tclass, p_ae->avd.seqno);
tsid, tclass, avd->seqno);
else
rc = -EACCES;
}
Expand Down

0 comments on commit 21193dc

Please sign in to comment.