8021q: fix a memory leak for VLAN 0 device
[pandora-kernel.git] / net / netlabel / netlabel_kapi.c
index 9c24de1..290c7bb 100644 (file)
@@ -111,8 +111,6 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
        struct netlbl_domaddr_map *addrmap = NULL;
        struct netlbl_domaddr4_map *map4 = NULL;
        struct netlbl_domaddr6_map *map6 = NULL;
-       const struct in_addr *addr4, *mask4;
-       const struct in6_addr *addr6, *mask6;
 
        entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
        if (entry == NULL)
@@ -133,9 +131,9 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
                INIT_LIST_HEAD(&addrmap->list6);
 
                switch (family) {
-               case AF_INET:
-                       addr4 = addr;
-                       mask4 = mask;
+               case AF_INET: {
+                       const struct in_addr *addr4 = addr;
+                       const struct in_addr *mask4 = mask;
                        map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
                        if (map4 == NULL)
                                goto cfg_unlbl_map_add_failure;
@@ -148,9 +146,11 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
                        if (ret_val != 0)
                                goto cfg_unlbl_map_add_failure;
                        break;
-               case AF_INET6:
-                       addr6 = addr;
-                       mask6 = mask;
+                       }
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+               case AF_INET6: {
+                       const struct in6_addr *addr6 = addr;
+                       const struct in6_addr *mask6 = mask;
                        map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
                        if (map6 == NULL)
                                goto cfg_unlbl_map_add_failure;
@@ -162,11 +162,13 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
                        map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3];
                        ipv6_addr_copy(&map6->list.mask, mask6);
                        map6->list.valid = 1;
-                       ret_val = netlbl_af4list_add(&map4->list,
-                                                    &addrmap->list4);
+                       ret_val = netlbl_af6list_add(&map6->list,
+                                                    &addrmap->list6);
                        if (ret_val != 0)
                                goto cfg_unlbl_map_add_failure;
                        break;
+                       }
+#endif /* IPv6 */
                default:
                        goto cfg_unlbl_map_add_failure;
                        break;
@@ -225,9 +227,11 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
        case AF_INET:
                addr_len = sizeof(struct in_addr);
                break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
        case AF_INET6:
                addr_len = sizeof(struct in6_addr);
                break;
+#endif /* IPv6 */
        default:
                return -EPFNOSUPPORT;
        }
@@ -266,9 +270,11 @@ int netlbl_cfg_unlbl_static_del(struct net *net,
        case AF_INET:
                addr_len = sizeof(struct in_addr);
                break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
        case AF_INET6:
                addr_len = sizeof(struct in6_addr);
                break;
+#endif /* IPv6 */
        default:
                return -EPFNOSUPPORT;
        }
@@ -517,7 +523,7 @@ int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
 
 /**
  * netlbl_secattr_catmap_setbit - Set a bit in a LSM secattr catmap
- * @catmap: the category bitmap
+ * @catmap: pointer to the category bitmap
  * @bit: the bit to set
  * @flags: memory allocation flags
  *
@@ -526,18 +532,25 @@ int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
  * negative values on failure.
  *
  */
-int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap,
+int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap **catmap,
                                 u32 bit,
                                 gfp_t flags)
 {
-       struct netlbl_lsm_secattr_catmap *iter = catmap;
+       struct netlbl_lsm_secattr_catmap *iter = *catmap;
        u32 node_bit;
        u32 node_idx;
 
        while (iter->next != NULL &&
               bit >= (iter->startbit + NETLBL_CATMAP_SIZE))
                iter = iter->next;
-       if (bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
+       if (bit < iter->startbit) {
+               iter = netlbl_secattr_catmap_alloc(flags);
+               if (iter == NULL)
+                       return -ENOMEM;
+               iter->next = *catmap;
+               iter->startbit = bit & ~(NETLBL_CATMAP_SIZE - 1);
+               *catmap = iter;
+       } else if (bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
                iter->next = netlbl_secattr_catmap_alloc(flags);
                if (iter->next == NULL)
                        return -ENOMEM;
@@ -555,7 +568,7 @@ int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap,
 
 /**
  * netlbl_secattr_catmap_setrng - Set a range of bits in a LSM secattr catmap
- * @catmap: the category bitmap
+ * @catmap: pointer to the category bitmap
  * @start: the starting bit
  * @end: the last bit in the string
  * @flags: memory allocation flags
@@ -565,15 +578,16 @@ int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap,
  * on success, negative values on failure.
  *
  */
-int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
+int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap **catmap,
                                 u32 start,
                                 u32 end,
                                 gfp_t flags)
 {
        int ret_val = 0;
-       struct netlbl_lsm_secattr_catmap *iter = catmap;
+       struct netlbl_lsm_secattr_catmap *iter = *catmap;
        u32 iter_max_spot;
        u32 spot;
+       u32 orig_spot = iter->startbit;
 
        /* XXX - This could probably be made a bit faster by combining writes
         * to the catmap instead of setting a single bit each time, but for
@@ -591,7 +605,9 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
                        iter = iter->next;
                        iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
                }
-               ret_val = netlbl_secattr_catmap_setbit(iter, spot, GFP_ATOMIC);
+               ret_val = netlbl_secattr_catmap_setbit(&iter, spot, flags);
+               if (iter->startbit < orig_spot)
+                       *catmap = iter;
        }
 
        return ret_val;
@@ -694,7 +710,11 @@ socket_setattr_return:
  */
 void netlbl_sock_delattr(struct sock *sk)
 {
-       cipso_v4_sock_delattr(sk);
+       switch (sk->sk_family) {
+       case AF_INET:
+               cipso_v4_sock_delattr(sk);
+               break;
+       }
 }
 
 /**
@@ -873,7 +893,11 @@ req_setattr_return:
 */
 void netlbl_req_delattr(struct request_sock *req)
 {
-       cipso_v4_req_delattr(req);
+       switch (req->rsk_ops->family) {
+       case AF_INET:
+               cipso_v4_req_delattr(req);
+               break;
+       }
 }
 
 /**