Commit cf7260ee authored by Vlad Yasevich's avatar Vlad Yasevich Committed by Adrian Bunk

SCTP: Reject sctp packets with broadcast addresses.

Make SCTP handle broadcast properly
Signed-off-by: default avatarVlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: default avatarSridhar Samudrala <sri@us.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarAdrian Bunk <bunk@stusta.de>
parent c92faf3e
...@@ -545,7 +545,8 @@ struct sctp_af { ...@@ -545,7 +545,8 @@ struct sctp_af {
int (*to_addr_param) (const union sctp_addr *, int (*to_addr_param) (const union sctp_addr *,
union sctp_addr_param *); union sctp_addr_param *);
int (*addr_valid) (union sctp_addr *, int (*addr_valid) (union sctp_addr *,
struct sctp_sock *); struct sctp_sock *,
const struct sk_buff *);
sctp_scope_t (*scope) (union sctp_addr *); sctp_scope_t (*scope) (union sctp_addr *);
void (*inaddr_any) (union sctp_addr *, unsigned short); void (*inaddr_any) (union sctp_addr *, unsigned short);
int (*is_any) (const union sctp_addr *); int (*is_any) (const union sctp_addr *);
......
...@@ -169,7 +169,8 @@ int sctp_rcv(struct sk_buff *skb) ...@@ -169,7 +169,8 @@ int sctp_rcv(struct sk_buff *skb)
* IP broadcast addresses cannot be used in an SCTP transport * IP broadcast addresses cannot be used in an SCTP transport
* address." * address."
*/ */
if (!af->addr_valid(&src, NULL) || !af->addr_valid(&dest, NULL)) if (!af->addr_valid(&src, NULL, skb) ||
!af->addr_valid(&dest, NULL, skb))
goto discard_it; goto discard_it;
asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport); asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport);
......
...@@ -523,7 +523,9 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp) ...@@ -523,7 +523,9 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
* Return 0 - If the address is a non-unicast or an illegal address. * Return 0 - If the address is a non-unicast or an illegal address.
* Return 1 - If the address is a unicast. * Return 1 - If the address is a unicast.
*/ */
static int sctp_v6_addr_valid(union sctp_addr *addr, struct sctp_sock *sp) static int sctp_v6_addr_valid(union sctp_addr *addr,
struct sctp_sock *sp,
const struct sk_buff *skb)
{ {
int ret = ipv6_addr_type(&addr->v6.sin6_addr); int ret = ipv6_addr_type(&addr->v6.sin6_addr);
...@@ -537,7 +539,7 @@ static int sctp_v6_addr_valid(union sctp_addr *addr, struct sctp_sock *sp) ...@@ -537,7 +539,7 @@ static int sctp_v6_addr_valid(union sctp_addr *addr, struct sctp_sock *sp)
if (sp && ipv6_only_sock(sctp_opt2sk(sp))) if (sp && ipv6_only_sock(sctp_opt2sk(sp)))
return 0; return 0;
sctp_v6_map_v4(addr); sctp_v6_map_v4(addr);
return sctp_get_af_specific(AF_INET)->addr_valid(addr, sp); return sctp_get_af_specific(AF_INET)->addr_valid(addr, sp, skb);
} }
/* Is this a non-unicast address */ /* Is this a non-unicast address */
......
...@@ -365,12 +365,18 @@ static int sctp_v4_is_any(const union sctp_addr *addr) ...@@ -365,12 +365,18 @@ static int sctp_v4_is_any(const union sctp_addr *addr)
* Return 0 - If the address is a non-unicast or an illegal address. * Return 0 - If the address is a non-unicast or an illegal address.
* Return 1 - If the address is a unicast. * Return 1 - If the address is a unicast.
*/ */
static int sctp_v4_addr_valid(union sctp_addr *addr, struct sctp_sock *sp) static int sctp_v4_addr_valid(union sctp_addr *addr,
struct sctp_sock *sp,
const struct sk_buff *skb)
{ {
/* Is this a non-unicast address or a unusable SCTP address? */ /* Is this a non-unicast address or a unusable SCTP address? */
if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr)) if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr))
return 0; return 0;
/* Is this a broadcast address? */
if (skb && ((struct rtable *)skb->dst)->rt_flags & RTCF_BROADCAST)
return 0;
return 1; return 1;
} }
......
...@@ -172,7 +172,7 @@ static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr, ...@@ -172,7 +172,7 @@ static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr,
return -EINVAL; return -EINVAL;
/* Is this a valid SCTP address? */ /* Is this a valid SCTP address? */
if (!af->addr_valid(addr, sctp_sk(sk))) if (!af->addr_valid(addr, sctp_sk(sk), NULL))
return -EINVAL; return -EINVAL;
if (!sctp_sk(sk)->pf->send_verify(sctp_sk(sk), (addr))) if (!sctp_sk(sk)->pf->send_verify(sctp_sk(sk), (addr)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment