Commit 5636bef7 authored by Vlad Yasevich's avatar Vlad Yasevich Committed by David S. Miller
Browse files

[SCTP]: Reject sctp packets with broadcast addresses.

parent 402d68c4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -555,7 +555,8 @@ struct sctp_af {
	int		(*to_addr_param) (const union sctp_addr *,
					  union sctp_addr_param *); 
	int		(*addr_valid)	(union sctp_addr *,
					 struct sctp_sock *);
					 struct sctp_sock *,
					 const struct sk_buff *);
	sctp_scope_t	(*scope) (union sctp_addr *);
	void		(*inaddr_any)	(union sctp_addr *, unsigned short);
	int		(*is_any)	(const union sctp_addr *);
+2 −1
Original line number Diff line number Diff line
@@ -170,7 +170,8 @@ int sctp_rcv(struct sk_buff *skb)
	 * IP broadcast addresses cannot be used in an SCTP transport
	 * 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;

	asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport);
+4 −2
Original line number Diff line number Diff line
@@ -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 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);

@@ -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)))
			return 0;
		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 */
+7 −1
Original line number Diff line number Diff line
@@ -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 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? */
	if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr))
		return 0;

 	/* Is this a broadcast address? */
 	if (skb && ((struct rtable *)skb->dst)->rt_flags & RTCF_BROADCAST)
 		return 0;

	return 1;
}

+1 −1
Original line number Diff line number Diff line
@@ -172,7 +172,7 @@ static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr,
		return -EINVAL;

	/* 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;

	if (!sctp_sk(sk)->pf->send_verify(sctp_sk(sk), (addr)))