cipso_ipv4.c (9d066a252786e1a18484a6283f82614d42a9f4ac) cipso_ipv4.c (3faa8f982f958961fda68b8d63e682fe77a032d4)
1/*
2 * CIPSO - Commercial IP Security Option
3 *
4 * This is an implementation of the CIPSO 2.2 protocol as specified in
5 * draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in
6 * FIPS-188. While CIPSO never became a full IETF RFC standard many vendors
7 * have chosen to adopt the protocol and over the years it has become a
8 * de-facto standard for labeled networking.

--- 121 unchanged lines hidden (view full) ---

130 */
131#define CIPSO_V4_TAG_LOC_BLEN 6
132
133/*
134 * Helper Functions
135 */
136
137/**
1/*
2 * CIPSO - Commercial IP Security Option
3 *
4 * This is an implementation of the CIPSO 2.2 protocol as specified in
5 * draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in
6 * FIPS-188. While CIPSO never became a full IETF RFC standard many vendors
7 * have chosen to adopt the protocol and over the years it has become a
8 * de-facto standard for labeled networking.

--- 121 unchanged lines hidden (view full) ---

130 */
131#define CIPSO_V4_TAG_LOC_BLEN 6
132
133/*
134 * Helper Functions
135 */
136
137/**
138 * cipso_v4_bitmap_walk - Walk a bitmap looking for a bit
139 * @bitmap: the bitmap
140 * @bitmap_len: length in bits
141 * @offset: starting offset
142 * @state: if non-zero, look for a set (1) bit else look for a cleared (0) bit
143 *
144 * Description:
145 * Starting at @offset, walk the bitmap from left to right until either the
146 * desired bit is found or we reach the end. Return the bit offset, -1 if
147 * not found, or -2 if error.
148 */
149static int cipso_v4_bitmap_walk(const unsigned char *bitmap,
150 u32 bitmap_len,
151 u32 offset,
152 u8 state)
153{
154 u32 bit_spot;
155 u32 byte_offset;
156 unsigned char bitmask;
157 unsigned char byte;
158
159 /* gcc always rounds to zero when doing integer division */
160 byte_offset = offset / 8;
161 byte = bitmap[byte_offset];
162 bit_spot = offset;
163 bitmask = 0x80 >> (offset % 8);
164
165 while (bit_spot < bitmap_len) {
166 if ((state && (byte & bitmask) == bitmask) ||
167 (state == 0 && (byte & bitmask) == 0))
168 return bit_spot;
169
170 bit_spot++;
171 bitmask >>= 1;
172 if (bitmask == 0) {
173 byte = bitmap[++byte_offset];
174 bitmask = 0x80;
175 }
176 }
177
178 return -1;
179}
180
181/**
182 * cipso_v4_bitmap_setbit - Sets a single bit in a bitmap
183 * @bitmap: the bitmap
184 * @bit: the bit
185 * @state: if non-zero, set the bit (1) else clear the bit (0)
186 *
187 * Description:
188 * Set a single bit in the bitmask. Returns zero on success, negative values
189 * on error.
190 */
191static void cipso_v4_bitmap_setbit(unsigned char *bitmap,
192 u32 bit,
193 u8 state)
194{
195 u32 byte_spot;
196 u8 bitmask;
197
198 /* gcc always rounds to zero when doing integer division */
199 byte_spot = bit / 8;
200 bitmask = 0x80 >> (bit % 8);
201 if (state)
202 bitmap[byte_spot] |= bitmask;
203 else
204 bitmap[byte_spot] &= ~bitmask;
205}
206
207/**
208 * cipso_v4_cache_entry_free - Frees a cache entry
209 * @entry: the entry to free
210 *
211 * Description:
212 * This function frees the memory associated with a cache entry including the
213 * LSM cache data if there are no longer any users, i.e. reference count == 0.
214 *
215 */

--- 619 unchanged lines hidden (view full) ---

835
836 switch (doi_def->type) {
837 case CIPSO_V4_MAP_PASS:
838 return 0;
839 case CIPSO_V4_MAP_TRANS:
840 cipso_cat_size = doi_def->map.std->cat.cipso_size;
841 cipso_array = doi_def->map.std->cat.cipso;
842 for (;;) {
138 * cipso_v4_cache_entry_free - Frees a cache entry
139 * @entry: the entry to free
140 *
141 * Description:
142 * This function frees the memory associated with a cache entry including the
143 * LSM cache data if there are no longer any users, i.e. reference count == 0.
144 *
145 */

--- 619 unchanged lines hidden (view full) ---

765
766 switch (doi_def->type) {
767 case CIPSO_V4_MAP_PASS:
768 return 0;
769 case CIPSO_V4_MAP_TRANS:
770 cipso_cat_size = doi_def->map.std->cat.cipso_size;
771 cipso_array = doi_def->map.std->cat.cipso;
772 for (;;) {
843 cat = cipso_v4_bitmap_walk(bitmap,
844 bitmap_len_bits,
845 cat + 1,
846 1);
773 cat = netlbl_bitmap_walk(bitmap,
774 bitmap_len_bits,
775 cat + 1,
776 1);
847 if (cat < 0)
848 break;
849 if (cat >= cipso_cat_size ||
850 cipso_array[cat] >= CIPSO_V4_INV_CAT)
851 return -EFAULT;
852 }
853
854 if (cat == -1)

--- 49 unchanged lines hidden (view full) ---

904 return -EPERM;
905 net_spot = host_cat_array[host_spot];
906 if (net_spot >= CIPSO_V4_INV_CAT)
907 return -EPERM;
908 break;
909 }
910 if (net_spot >= net_clen_bits)
911 return -ENOSPC;
777 if (cat < 0)
778 break;
779 if (cat >= cipso_cat_size ||
780 cipso_array[cat] >= CIPSO_V4_INV_CAT)
781 return -EFAULT;
782 }
783
784 if (cat == -1)

--- 49 unchanged lines hidden (view full) ---

834 return -EPERM;
835 net_spot = host_cat_array[host_spot];
836 if (net_spot >= CIPSO_V4_INV_CAT)
837 return -EPERM;
838 break;
839 }
840 if (net_spot >= net_clen_bits)
841 return -ENOSPC;
912 cipso_v4_bitmap_setbit(net_cat, net_spot, 1);
842 netlbl_bitmap_setbit(net_cat, net_spot, 1);
913
914 if (net_spot > net_spot_max)
915 net_spot_max = net_spot;
916 }
917
918 if (++net_spot_max % 8)
919 return net_spot_max / 8 + 1;
920 return net_spot_max / 8;

--- 25 unchanged lines hidden (view full) ---

946 u32 *net_cat_array = NULL;
947
948 if (doi_def->type == CIPSO_V4_MAP_TRANS) {
949 net_cat_size = doi_def->map.std->cat.cipso_size;
950 net_cat_array = doi_def->map.std->cat.cipso;
951 }
952
953 for (;;) {
843
844 if (net_spot > net_spot_max)
845 net_spot_max = net_spot;
846 }
847
848 if (++net_spot_max % 8)
849 return net_spot_max / 8 + 1;
850 return net_spot_max / 8;

--- 25 unchanged lines hidden (view full) ---

876 u32 *net_cat_array = NULL;
877
878 if (doi_def->type == CIPSO_V4_MAP_TRANS) {
879 net_cat_size = doi_def->map.std->cat.cipso_size;
880 net_cat_array = doi_def->map.std->cat.cipso;
881 }
882
883 for (;;) {
954 net_spot = cipso_v4_bitmap_walk(net_cat,
955 net_clen_bits,
956 net_spot + 1,
957 1);
884 net_spot = netlbl_bitmap_walk(net_cat,
885 net_clen_bits,
886 net_spot + 1,
887 1);
958 if (net_spot < 0) {
959 if (net_spot == -2)
960 return -EFAULT;
961 return 0;
962 }
963
964 switch (doi_def->type) {
965 case CIPSO_V4_MAP_PASS:

--- 962 unchanged lines hidden (view full) ---

1928 memcpy(opt->opt.__data, buf, buf_len);
1929 opt->opt.optlen = opt_len;
1930 opt->opt.cipso = sizeof(struct iphdr);
1931 kfree(buf);
1932 buf = NULL;
1933
1934 sk_inet = inet_sk(sk);
1935
888 if (net_spot < 0) {
889 if (net_spot == -2)
890 return -EFAULT;
891 return 0;
892 }
893
894 switch (doi_def->type) {
895 case CIPSO_V4_MAP_PASS:

--- 962 unchanged lines hidden (view full) ---

1858 memcpy(opt->opt.__data, buf, buf_len);
1859 opt->opt.optlen = opt_len;
1860 opt->opt.cipso = sizeof(struct iphdr);
1861 kfree(buf);
1862 buf = NULL;
1863
1864 sk_inet = inet_sk(sk);
1865
1936 old = rcu_dereference_protected(sk_inet->inet_opt,
1937 lockdep_sock_is_held(sk));
1866 old = rcu_dereference_protected(sk_inet->inet_opt, sock_owned_by_user(sk));
1938 if (sk_inet->is_icsk) {
1939 sk_conn = inet_csk(sk);
1940 if (old)
1941 sk_conn->icsk_ext_hdr_len -= old->opt.optlen;
1942 sk_conn->icsk_ext_hdr_len += opt->opt.optlen;
1943 sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
1944 }
1945 rcu_assign_pointer(sk_inet->inet_opt, opt);

--- 413 unchanged lines hidden ---
1867 if (sk_inet->is_icsk) {
1868 sk_conn = inet_csk(sk);
1869 if (old)
1870 sk_conn->icsk_ext_hdr_len -= old->opt.optlen;
1871 sk_conn->icsk_ext_hdr_len += opt->opt.optlen;
1872 sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
1873 }
1874 rcu_assign_pointer(sk_inet->inet_opt, opt);

--- 413 unchanged lines hidden ---