summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2013-06-28 13:47:07 -0700
committerChanho Park <chanho61.park@samsung.com>2014-11-18 11:46:05 +0900
commit052694ee35c601ca851828e03ce09f91fee7a372 (patch)
tree48b2ebdc5e93ebedf9c0ad8214ce18450b4e0460 /security
parent0f09dfd255b6770477c12f9e3b74bc8fc888af81 (diff)
downloadlinux-3.10-052694ee35c601ca851828e03ce09f91fee7a372.tar.gz
linux-3.10-052694ee35c601ca851828e03ce09f91fee7a372.tar.bz2
linux-3.10-052694ee35c601ca851828e03ce09f91fee7a372.zip
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 Change-Id: I22a2fd758b5a7764cbeb3ebf9f4dadd12d5b170b Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Signed-off-by: Ɓukasz Stelmach <l.stelmach@samsung.com>
Diffstat (limited to 'security')
-rw-r--r--security/smack/smack.h8
-rw-r--r--security/smack/smack_lsm.c30
-rw-r--r--security/smack/smackfs.c2
3 files changed, 31 insertions, 9 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h
index e80597a3048..076b8e8a51a 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -168,9 +168,13 @@ struct smk_port_label {
#define SMACK_CIPSO_DOI_INVALID -1 /* Not a DOI */
#define SMACK_CIPSO_DIRECT_DEFAULT 250 /* Arbitrary */
#define SMACK_CIPSO_MAPPED_DEFAULT 251 /* Also arbitrary */
-#define SMACK_CIPSO_MAXCATVAL 63 /* Bigger gets harder */
#define SMACK_CIPSO_MAXLEVEL 255 /* CIPSO 2.2 standard */
-#define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */
+/*
+ * CIPSO 2.2 standard is 239, but Smack wants to use the
+ * categories in a structured way that limits the value to
+ * the bits in 23 bytes, hence the unusual number.
+ */
+#define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */
/*
* Flag for transmute access
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index f70a0fae691..19de5e23768 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3063,6 +3063,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) {
/*
@@ -3079,12 +3081,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();
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 269b270c647..a07e93f00a0 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -890,7 +890,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
for (i = 0; i < catlen; i++) {
rule += SMK_DIGITLEN;
ret = sscanf(rule, "%u", &cat);
- if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL)
+ if (ret != 1 || cat > SMACK_CIPSO_MAXCATNUM)
goto out;
smack_catset_bit(cat, mapcatset);