summaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_make_chunk.c
diff options
context:
space:
mode:
authorWei Yongjun <yjwei@cn.fujitsu.com>2011-04-19 21:30:51 +0000
committerDavid S. Miller <davem@davemloft.net>2011-04-20 01:51:05 -0700
commitde6becdc0844ff92b38ffd9f0c4db1d3de02835f (patch)
treef52df91a347ece7e4efc09ca2974e8e38f38a3f8 /net/sctp/sm_make_chunk.c
parent85c5ed4e44a262344ce43b4bf23204107923ca95 (diff)
sctp: fix to check the source address of COOKIE-ECHO chunk
SCTP does not check whether the source address of COOKIE-ECHO chunk is the original address of INIT chunk or part of the any address parameters saved in COOKIE in CLOSED state. So even if the COOKIE-ECHO chunk is from any address but with correct COOKIE, the COOKIE-ECHO chunk still be accepted. If the COOKIE is not from a valid address, the assoc should not be established. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/sm_make_chunk.c')
-rw-r--r--net/sctp/sm_make_chunk.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index f87ccb11a52..a7b65e9e44b 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2242,14 +2242,17 @@ int sctp_verify_init(const struct sctp_association *asoc,
* Returns 0 on failure, else success.
* FIXME: This is an association method.
*/
-int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
+int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
const union sctp_addr *peer_addr,
sctp_init_chunk_t *peer_init, gfp_t gfp)
{
union sctp_params param;
struct sctp_transport *transport;
struct list_head *pos, *temp;
+ struct sctp_af *af;
+ union sctp_addr addr;
char *cookie;
+ int src_match = 0;
/* We must include the address that the INIT packet came from.
* This is the only address that matters for an INIT packet.
@@ -2261,18 +2264,31 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
* added as the primary transport. The source address seems to
* be a a better choice than any of the embedded addresses.
*/
- if (peer_addr) {
- if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
- goto nomem;
- }
+ if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
+ goto nomem;
+
+ if (sctp_cmp_addr_exact(sctp_source(chunk), peer_addr))
+ src_match = 1;
/* Process the initialization parameters. */
sctp_walk_params(param, peer_init, init_hdr.params) {
+ if (!src_match && (param.p->type == SCTP_PARAM_IPV4_ADDRESS ||
+ param.p->type == SCTP_PARAM_IPV6_ADDRESS)) {
+ af = sctp_get_af_specific(param_type2af(param.p->type));
+ af->from_addr_param(&addr, param.addr,
+ chunk->sctp_hdr->source, 0);
+ if (sctp_cmp_addr_exact(sctp_source(chunk), &addr))
+ src_match = 1;
+ }
if (!sctp_process_param(asoc, param, peer_addr, gfp))
goto clean_up;
}
+ /* source address of chunk may not match any valid address */
+ if (!src_match)
+ goto clean_up;
+
/* AUTH: After processing the parameters, make sure that we
* have all the required info to potentially do authentications.
*/