ソースを参照

[SCTP]: Reject sctp packets with broadcast addresses.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Vlad Yasevich 19 年 前
コミット
5636bef732
5 ファイル変更16 行追加6 行削除
  1. 2 1
      include/net/sctp/structs.h
  2. 2 1
      net/sctp/input.c
  3. 4 2
      net/sctp/ipv6.c
  4. 7 1
      net/sctp/protocol.c
  5. 1 1
      net/sctp/socket.c

+ 2 - 1
include/net/sctp/structs.h

@@ -555,7 +555,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 *);

+ 2 - 1
net/sctp/input.c

@@ -170,7 +170,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);

+ 4 - 2
net/sctp/ipv6.c

@@ -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)
 		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 */

+ 7 - 1
net/sctp/protocol.c

@@ -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;
 }
 }
 
 

+ 1 - 1
net/sctp/socket.c

@@ -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)))