]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/cipso_ipv4.c
[NETLINK]: Do precise netlink message allocations where possible
[linux-2.6-omap-h63xx.git] / net / ipv4 / cipso_ipv4.c
index bde8ccaa15316f2521edda94de64f1ac67c4468a..6460233407c786f4138671765786d98db3bab6ae 100644 (file)
@@ -773,13 +773,15 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
 {
        int cat = -1;
        u32 bitmap_len_bits = bitmap_len * 8;
-       u32 cipso_cat_size = doi_def->map.std->cat.cipso_size;
-       u32 *cipso_array = doi_def->map.std->cat.cipso;
+       u32 cipso_cat_size;
+       u32 *cipso_array;
 
        switch (doi_def->type) {
        case CIPSO_V4_MAP_PASS:
                return 0;
        case CIPSO_V4_MAP_STD:
+               cipso_cat_size = doi_def->map.std->cat.cipso_size;
+               cipso_array = doi_def->map.std->cat.cipso;
                for (;;) {
                        cat = cipso_v4_bitmap_walk(bitmap,
                                                   bitmap_len_bits,
@@ -825,19 +827,21 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
        u32 net_spot_max = 0;
        u32 host_clen_bits = host_cat_len * 8;
        u32 net_clen_bits = net_cat_len * 8;
-       u32 host_cat_size = doi_def->map.std->cat.local_size;
-       u32 *host_cat_array = doi_def->map.std->cat.local;
+       u32 host_cat_size;
+       u32 *host_cat_array;
 
        switch (doi_def->type) {
        case CIPSO_V4_MAP_PASS:
-               net_spot_max = host_cat_len - 1;
-               while (net_spot_max > 0 && host_cat[net_spot_max] == 0)
+               net_spot_max = host_cat_len;
+               while (net_spot_max > 0 && host_cat[net_spot_max - 1] == 0)
                        net_spot_max--;
                if (net_spot_max > net_cat_len)
                        return -EINVAL;
                memcpy(net_cat, host_cat, net_spot_max);
                return net_spot_max;
        case CIPSO_V4_MAP_STD:
+               host_cat_size = doi_def->map.std->cat.local_size;
+               host_cat_array = doi_def->map.std->cat.local;
                for (;;) {
                        host_spot = cipso_v4_bitmap_walk(host_cat,
                                                         host_clen_bits,
@@ -893,8 +897,8 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
        int net_spot = -1;
        u32 net_clen_bits = net_cat_len * 8;
        u32 host_clen_bits = host_cat_len * 8;
-       u32 net_cat_size = doi_def->map.std->cat.cipso_size;
-       u32 *net_cat_array = doi_def->map.std->cat.cipso;
+       u32 net_cat_size;
+       u32 *net_cat_array;
 
        switch (doi_def->type) {
        case CIPSO_V4_MAP_PASS:
@@ -903,6 +907,8 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
                memcpy(host_cat, net_cat, net_cat_len);
                return net_cat_len;
        case CIPSO_V4_MAP_STD:
+               net_cat_size = doi_def->map.std->cat.cipso_size;
+               net_cat_array = doi_def->map.std->cat.cipso;
                for (;;) {
                        net_spot = cipso_v4_bitmap_walk(net_cat,
                                                        net_clen_bits,
@@ -1301,7 +1307,8 @@ int cipso_v4_socket_setattr(const struct socket *sock,
 
        /* We can't use ip_options_get() directly because it makes a call to
         * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
-        * we can't block here. */
+        * we won't always have CAP_NET_RAW even though we _always_ want to
+        * set the IPOPT_CIPSO option. */
        opt_len = (buf_len + 3) & ~3;
        opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
        if (opt == NULL) {
@@ -1311,11 +1318,9 @@ int cipso_v4_socket_setattr(const struct socket *sock,
        memcpy(opt->__data, buf, buf_len);
        opt->optlen = opt_len;
        opt->is_data = 1;
+       opt->cipso = sizeof(struct iphdr);
        kfree(buf);
        buf = NULL;
-       ret_val = ip_options_compile(opt, NULL);
-       if (ret_val != 0)
-               goto socket_setattr_failure;
 
        sk_inet = inet_sk(sk);
        if (sk_inet->is_icsk) {