]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/cipso_ipv4.c
NetLabel: check for a CIPSOv4 option before we do call into the CIPSOv4 layer
[linux-2.6-omap-h63xx.git] / net / ipv4 / cipso_ipv4.c
index 6460233407c786f4138671765786d98db3bab6ae..fb5d913f5815dd8462a3c9bb69787b3ac963454c 100644 (file)
@@ -319,6 +319,7 @@ static int cipso_v4_cache_check(const unsigned char *key,
                        entry->activity += 1;
                        atomic_inc(&entry->lsm_data->refcount);
                        secattr->cache = entry->lsm_data;
+                       secattr->flags |= NETLBL_SECATTR_CACHE;
                        if (prev_entry == NULL) {
                                spin_unlock_bh(&cipso_v4_cache[bkt].lock);
                                return 0;
@@ -377,12 +378,11 @@ int cipso_v4_cache_add(const struct sk_buff *skb,
        entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
        if (entry == NULL)
                return -ENOMEM;
-       entry->key = kmalloc(cipso_ptr_len, GFP_ATOMIC);
+       entry->key = kmemdup(cipso_ptr, cipso_ptr_len, GFP_ATOMIC);
        if (entry->key == NULL) {
                ret_val = -ENOMEM;
                goto cache_add_failure;
        }
-       memcpy(entry->key, cipso_ptr, cipso_ptr_len);
        entry->key_len = cipso_ptr_len;
        entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len);
        atomic_inc(&secattr->cache->refcount);
@@ -966,7 +966,7 @@ static int cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
 
        buf[0] = IPOPT_CIPSO;
        buf[1] = CIPSO_V4_HDR_LEN + len;
-       *(u32 *)&buf[2] = htonl(doi_def->doi);
+       *(__be32 *)&buf[2] = htonl(doi_def->doi);
 
        return 0;
 }
@@ -992,12 +992,15 @@ static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
                               unsigned char **buffer,
                               u32 *buffer_len)
 {
-       int ret_val = -EPERM;
+       int ret_val;
        unsigned char *buf = NULL;
        u32 buf_len;
        u32 level;
 
-       if (secattr->mls_cat) {
+       if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0)
+               return -EPERM;
+
+       if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
                buf = kzalloc(CIPSO_V4_HDR_LEN + 4 + CIPSO_V4_TAG1_CAT_LEN,
                              GFP_ATOMIC);
                if (buf == NULL)
@@ -1014,10 +1017,10 @@ static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
                /* This will send packets using the "optimized" format when
                 * possibile as specified in  section 3.4.2.6 of the
                 * CIPSO draft. */
-               if (cipso_v4_rbm_optfmt && (ret_val > 0 && ret_val < 10))
-                       ret_val = 10;
-
-               buf_len = 4 + ret_val;
+               if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10)
+                       buf_len = 14;
+               else
+                       buf_len = 4 + ret_val;
        } else {
                buf = kzalloc(CIPSO_V4_HDR_LEN + 4, GFP_ATOMIC);
                if (buf == NULL)
@@ -1071,7 +1074,7 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
        if (ret_val != 0)
                return ret_val;
        secattr->mls_lvl = level;
-       secattr->mls_lvl_vld = 1;
+       secattr->flags |= NETLBL_SECATTR_MLS_LVL;
 
        if (tag_len > 4) {
                switch (doi_def->type) {
@@ -1095,8 +1098,10 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
                if (ret_val < 0) {
                        kfree(secattr->mls_cat);
                        return ret_val;
+               } else if (ret_val > 0) {
+                       secattr->mls_cat_len = ret_val;
+                       secattr->flags |= NETLBL_SECATTR_MLS_CAT;
                }
-               secattr->mls_cat_len = ret_val;
        }
 
        return 0;
@@ -1140,7 +1145,7 @@ int cipso_v4_validate(unsigned char **option)
        }
 
        rcu_read_lock();
-       doi_def = cipso_v4_doi_getdef(ntohl(*((u32 *)&opt[2])));
+       doi_def = cipso_v4_doi_getdef(ntohl(*((__be32 *)&opt[2])));
        if (doi_def == NULL) {
                err_offset = 2;
                goto validate_return_locked;
@@ -1370,7 +1375,7 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
        if (ret_val == 0)
                return ret_val;
 
-       doi = ntohl(*(u32 *)&cipso_ptr[2]);
+       doi = ntohl(*(__be32 *)&cipso_ptr[2]);
        rcu_read_lock();
        doi_def = cipso_v4_doi_getdef(doi);
        if (doi_def == NULL) {
@@ -1430,13 +1435,11 @@ int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
        u32 doi;
        struct cipso_v4_doi *doi_def;
 
-       if (!CIPSO_V4_OPTEXIST(skb))
-               return -ENOMSG;
        cipso_ptr = CIPSO_V4_OPTPTR(skb);
        if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0)
                return 0;
 
-       doi = ntohl(*(u32 *)&cipso_ptr[2]);
+       doi = ntohl(*(__be32 *)&cipso_ptr[2]);
        rcu_read_lock();
        doi_def = cipso_v4_doi_getdef(doi);
        if (doi_def == NULL)