From 677264e8fb73ea35a508700e19ce76c527576d1c Mon Sep 17 00:00:00 2001 From: Casey Schaufler Date: Fri, 28 Jun 2013 13:47:07 -0700 Subject: Smack: network label match fix The Smack code that matches incoming CIPSO tags with Smack labels reaches through the NetLabel interfaces and compares the network data with the CIPSO header associated with a Smack label. This was done in a ill advised attempt to optimize performance. It works so long as the categories fit in a single capset, but this isn't always the case. This patch changes the Smack code to use the appropriate NetLabel interfaces to compare the incoming CIPSO header with the CIPSO header associated with a label. It will always match the CIPSO headers correctly. Targeted for git://git.gitorious.org/smack-next/kernel.git Signed-off-by: Casey Schaufler --- security/smack/smack_lsm.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'security/smack/smack_lsm.c') diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index ce000a81caf7..19204e11c02c 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3066,6 +3066,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, { struct smack_known *skp; int found = 0; + int acat; + int kcat; if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { /* @@ -3082,12 +3084,28 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, list_for_each_entry(skp, &smack_known_list, list) { if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl) continue; - if (memcmp(sap->attr.mls.cat, - skp->smk_netlabel.attr.mls.cat, - SMK_CIPSOLEN) != 0) - continue; - found = 1; - break; + /* + * Compare the catsets. Use the netlbl APIs. + */ + if ((sap->flags & NETLBL_SECATTR_MLS_CAT) == 0) { + if ((skp->smk_netlabel.flags & + NETLBL_SECATTR_MLS_CAT) == 0) + found = 1; + break; + } + for (acat = -1, kcat = -1; acat == kcat; ) { + acat = netlbl_secattr_catmap_walk( + sap->attr.mls.cat, acat + 1); + kcat = netlbl_secattr_catmap_walk( + skp->smk_netlabel.attr.mls.cat, + kcat + 1); + if (acat < 0 || kcat < 0) + break; + } + if (acat == kcat) { + found = 1; + break; + } } rcu_read_unlock(); -- cgit v1.2.3