aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2012-06-01 01:54:56 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-01 14:18:29 -0400
commit20e2a86485967c385d7c7befc1646e4d1d39362e (patch)
treee08d5d8dd133a8548e9f5dd0f85e69241ec1e176
parentcc9b17ad29ecaa20bfe426a8d4dbfb94b13ff1cc (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.h29
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,
285static inline int cipso_v4_validate(const struct sk_buff *skb, 286static 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
312out:
313 *option = opt + err_offset;
314 return err_offset;
315
289} 316}
290#endif /* CONFIG_NETLABEL */ 317#endif /* CONFIG_NETLABEL */
291 318