]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
SCTP: Reject sctp packets with broadcast addresses.
authorVlad Yasevich <vladislav.yasevich@hp.com>
Sat, 26 Aug 2006 00:39:03 +0000 (02:39 +0200)
committerAdrian Bunk <bunk@stusta.de>
Sat, 26 Aug 2006 00:39:03 +0000 (02:39 +0200)
Make SCTP handle broadcast properly

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>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
include/net/sctp/structs.h
net/sctp/input.c
net/sctp/ipv6.c
net/sctp/protocol.c
net/sctp/socket.c

index acb2ce16e6d54c54fa1e8cb3b43ad85983f51263..bcd03e711f0dd3000f7d9198b321e5eecac39f4a 100644 (file)
@@ -545,7 +545,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 *);
index cb78b50868eee0c765884565dbdc4b6d4c2df01b..cf725888912822629ba9fbc1accb940c150f4242 100644 (file)
@@ -169,7 +169,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);
index 2e266129a764d2f0dc0edfaabdf483155b8cfdb1..c068d53e5415859f4e2ff2636cd765b7ff1042d6 100644 (file)
@@ -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 */
index de693b43c8eae08c18db0cbd2adf357a218e8eb3..1ebc274a10687f26465a7e18c15df613354ad1fb 100644 (file)
@@ -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;
 }
 
index 0f0ef2d87434938ad7b0cee85b73100ea3e38f4f..42a22355e027d87b9401d08984775d3fe19161cb 100644 (file)
@@ -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)))