Commit message: net: fix cipso packet validation when !NETLABEL

When CONFIG_NETLABEL is disabled, the cipso_v4_validate() function could loop
forever in the main loop if opt[opt_iter +1] == 0, this will causing a kernel
crash in an SMP system, since the CPU executing this function will
stall /not respond to IPIs.

This problem can be reproduced by running the IP Stack Integrity Checker
(http://isic.sourceforge.net) using the following command on a Linux machine
connected to DUT:

"icmpsic -s rand -d <DUT IP address> -r 123456"
wait (1-2 min)

Signed-off-by: Seif Mazareeb <seif@marvell.com>
Acked-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
CVE: CVE-2013-7470
CWE: CWE-703
Vulnerability description: cipso_v4_validate in include/net/cipso_ipv4.h in the Linux kernel before 3.11.7, when CONFIG_NETLABEL is disabled, allows attackers to cause a denial of service (infinite loop and crash), as demonstrated by icmpsic, a different vulnerability than CVE-2013-0310.

Project: linux
File: cipso_ipv4.h

static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def,
				   struct netlbl_audit *audit_info)
{
	return -ENOSYS;
}

Project: linux
File: cipso_ipv4.h

static inline int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
					     const char *domain)
{
	return 0;
}

Project: linux
File: cipso_ipv4.h

static inline int cipso_v4_doi_remove(u32 doi,
				      struct netlbl_audit *audit_info)
{
	return 0;
}

Project: linux
File: cipso_ipv4.h

static inline void cipso_v4_cache_invalidate(void)
{
	return;
}

Project: linux
File: cipso_ipv4.h

static inline void cipso_v4_req_delattr(struct request_sock *req)
{
	return;
}

Project: linux
File: cipso_ipv4.h

static inline int cipso_v4_sock_getattr(struct sock *sk,
					struct netlbl_lsm_secattr *secattr)
{
	return -ENOSYS;
}

Project: linux
File: cipso_ipv4.h

static inline int cipso_v4_req_setattr(struct request_sock *req,
				       const struct cipso_v4_doi *doi_def,
				       const struct netlbl_lsm_secattr *secattr)
{
	return -ENOSYS;
}

Project: linux
File: cipso_ipv4.h

static inline struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi)
{
	return NULL;
}

Project: linux
File: cipso_ipv4.h

static inline int cipso_v4_sock_setattr(struct sock *sk,
				      const struct cipso_v4_doi *doi_def,
				      const struct netlbl_lsm_secattr *secattr)
{
	return -ENOSYS;
}

Project: linux
File: cipso_ipv4.h

static inline int cipso_v4_validate(const struct sk_buff *skb,
				    unsigned char **option)
{
	unsigned char *opt = *option;
	unsigned char err_offset = 0;
	u8 opt_len = opt[1];
	u8 opt_iter;
	u8 tag_len;

	if (opt_len < 8) {
		err_offset = 1;
		goto out;
	}

	if (get_unaligned_be32(&opt[2]) == 0) {
		err_offset = 2;
		goto out;
	}

	for (opt_iter = 6; opt_iter < opt_len;) {
		tag_len = opt[opt_iter + 1];
		if ((tag_len == 0) || (opt[opt_iter + 1] > (opt_len - opt_iter))) {
			err_offset = opt_iter + 1;
			goto out;
		}
		opt_iter += tag_len;
	}

out:
	*option = opt + err_offset;
	return err_offset;

}

Project: linux
File: cipso_ipv4.h

static inline int cipso_v4_doi_walk(u32 *skip_cnt,
		     int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
		     void *cb_arg)
{
	return 0;
}

Project: linux
File: cipso_ipv4.h

static inline int cipso_v4_skbuff_setattr(struct sk_buff *skb,
				      const struct cipso_v4_doi *doi_def,
				      const struct netlbl_lsm_secattr *secattr)
{
	return -ENOSYS;
}

Project: linux
File: cipso_ipv4.h

static inline int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def,
					  const char *domain)
{
	return -ENOSYS;
}

Project: linux
File: cipso_ipv4.h

static inline int cipso_v4_skbuff_delattr(struct sk_buff *skb)
{
	return -ENOSYS;
}

Project: linux
File: cipso_ipv4.h

static inline void cipso_v4_doi_free(struct cipso_v4_doi *doi_def)
{
	return;
}

Project: linux
File: cipso_ipv4.h

static inline void cipso_v4_sock_delattr(struct sock *sk)
{
}

Project: linux
File: cipso_ipv4.h

static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
					  struct netlbl_lsm_secattr *secattr)
{
	return -ENOSYS;
}

Project: linux
File: cipso_ipv4.h

static inline void cipso_v4_error(struct sk_buff *skb,
				  int error,
				  u32 gateway)
{
	return;
}