diff options
author | Paul Moore <pmoore@redhat.com> | 2012-06-01 01:54:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-06-01 14:18:29 -0400 |
commit | 20e2a86485967c385d7c7befc1646e4d1d39362e (patch) | |
tree | e08d5d8dd133a8548e9f5dd0f85e69241ec1e176 | |
parent | cc9b17ad29ecaa20bfe426a8d4dbfb94b13ff1cc (diff) |
cipso: handle CIPSO options correctly when NetLabel is disabled
When NetLabel is not enabled, e.g. CONFIG_NETLABEL=n, and the system
receives a CIPSO tagged packet it is dropped (cipso_v4_validate()
returns non-zero). In most cases this is the correct and desired
behavior, however, in the case where we are simply forwarding the
traffic, e.g. acting as a network bridge, this becomes a problem.
This patch fixes the forwarding problem by providing the basic CIPSO
validation code directly in ip_options_compile() without the need for
the NetLabel or CIPSO code. The new validation code can not perform
any of the CIPSO option label/value verification that
cipso_v4_validate() does, but it can verify the basic CIPSO option
format.
The behavior when NetLabel is enabled is unchanged.
Signed-off-by: Paul Moore <pmoore@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/cipso_ipv4.h | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h index 9808877c2ab9..a7a683e30b64 100644 --- a/include/net/cipso_ipv4.h +++ b/include/net/cipso_ipv4.h | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <net/netlabel.h> | 42 | #include <net/netlabel.h> |
43 | #include <net/request_sock.h> | 43 | #include <net/request_sock.h> |
44 | #include <linux/atomic.h> | 44 | #include <linux/atomic.h> |
45 | #include <asm/unaligned.h> | ||
45 | 46 | ||
46 | /* known doi values */ | 47 | /* known doi values */ |
47 | #define CIPSO_V4_DOI_UNKNOWN 0x00000000 | 48 | #define CIPSO_V4_DOI_UNKNOWN 0x00000000 |
@@ -285,7 +286,33 @@ static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb, | |||
285 | static inline int cipso_v4_validate(const struct sk_buff *skb, | 286 | static inline int cipso_v4_validate(const struct sk_buff *skb, |
286 | unsigned char **option) | 287 | unsigned char **option) |
287 | { | 288 | { |
288 | return -ENOSYS; | 289 | unsigned char *opt = *option; |
290 | unsigned char err_offset = 0; | ||
291 | u8 opt_len = opt[1]; | ||
292 | u8 opt_iter; | ||
293 | |||
294 | if (opt_len < 8) { | ||
295 | err_offset = 1; | ||
296 | goto out; | ||
297 | } | ||
298 | |||
299 | if (get_unaligned_be32(&opt[2]) == 0) { | ||
300 | err_offset = 2; | ||
301 | goto out; | ||
302 | } | ||
303 | |||
304 | for (opt_iter = 6; opt_iter < opt_len;) { | ||
305 | if (opt[opt_iter + 1] > (opt_len - opt_iter)) { | ||
306 | err_offset = opt_iter + 1; | ||
307 | goto out; | ||
308 | } | ||
309 | opt_iter += opt[opt_iter + 1]; | ||
310 | } | ||
311 | |||
312 | out: | ||
313 | *option = opt + err_offset; | ||
314 | return err_offset; | ||
315 | |||
289 | } | 316 | } |
290 | #endif /* CONFIG_NETLABEL */ | 317 | #endif /* CONFIG_NETLABEL */ |
291 | 318 | ||