diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-11-29 08:50:35 -0500 |
---|---|---|
committer | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-11-29 10:17:41 -0500 |
commit | 8ee4be37e8ac28e79ae673d441e83c1f51e7ecfd (patch) | |
tree | 4b37a0656b4dae8b272edb94c7dcf11fdfa76bff /net | |
parent | 9baffaa689a50ef9480ecd9017ffd1480c807328 (diff) |
SCTP: Fix the supported extensions paramter
Supported extensions parameter was not coded right and ended up
over-writing memory or causing skb overflows. First, remove
the FWD_TSN support from as it shouldn't be there and also fix
the paramter encoding.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/sctp/sm_make_chunk.c | 23 |
1 files changed, 8 insertions, 15 deletions
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index a139469792a3..f4876291bb5e 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -77,6 +77,8 @@ static int sctp_process_param(struct sctp_association *asoc, | |||
77 | union sctp_params param, | 77 | union sctp_params param, |
78 | const union sctp_addr *peer_addr, | 78 | const union sctp_addr *peer_addr, |
79 | gfp_t gfp); | 79 | gfp_t gfp); |
80 | static void *sctp_addto_param(struct sctp_chunk *chunk, int len, | ||
81 | const void *data); | ||
80 | 82 | ||
81 | /* What was the inbound interface for this chunk? */ | 83 | /* What was the inbound interface for this chunk? */ |
82 | int sctp_chunk_iif(const struct sctp_chunk *chunk) | 84 | int sctp_chunk_iif(const struct sctp_chunk *chunk) |
@@ -207,11 +209,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
207 | 209 | ||
208 | chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types); | 210 | chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types); |
209 | chunksize += sizeof(ecap_param); | 211 | chunksize += sizeof(ecap_param); |
210 | if (sctp_prsctp_enable) { | 212 | |
211 | chunksize += sizeof(prsctp_param); | ||
212 | extensions[num_ext] = SCTP_CID_FWD_TSN; | ||
213 | num_ext += 1; | ||
214 | } | ||
215 | /* ADDIP: Section 4.2.7: | 213 | /* ADDIP: Section 4.2.7: |
216 | * An implementation supporting this extension [ADDIP] MUST list | 214 | * An implementation supporting this extension [ADDIP] MUST list |
217 | * the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and | 215 | * the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and |
@@ -297,7 +295,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
297 | htons(sizeof(sctp_supported_ext_param_t) + num_ext); | 295 | htons(sizeof(sctp_supported_ext_param_t) + num_ext); |
298 | sctp_addto_chunk(retval, sizeof(sctp_supported_ext_param_t), | 296 | sctp_addto_chunk(retval, sizeof(sctp_supported_ext_param_t), |
299 | &ext_param); | 297 | &ext_param); |
300 | sctp_addto_chunk(retval, num_ext, extensions); | 298 | sctp_addto_param(retval, num_ext, extensions); |
301 | } | 299 | } |
302 | 300 | ||
303 | if (sctp_prsctp_enable) | 301 | if (sctp_prsctp_enable) |
@@ -371,20 +369,12 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, | |||
371 | if (asoc->peer.ecn_capable) | 369 | if (asoc->peer.ecn_capable) |
372 | chunksize += sizeof(ecap_param); | 370 | chunksize += sizeof(ecap_param); |
373 | 371 | ||
374 | /* Tell peer that we'll do PR-SCTP only if peer advertised. */ | ||
375 | if (asoc->peer.prsctp_capable) { | ||
376 | chunksize += sizeof(prsctp_param); | ||
377 | extensions[num_ext] = SCTP_CID_FWD_TSN; | ||
378 | num_ext += 1; | ||
379 | } | ||
380 | |||
381 | if (sctp_addip_enable) { | 372 | if (sctp_addip_enable) { |
382 | extensions[num_ext] = SCTP_CID_ASCONF; | 373 | extensions[num_ext] = SCTP_CID_ASCONF; |
383 | extensions[num_ext+1] = SCTP_CID_ASCONF_ACK; | 374 | extensions[num_ext+1] = SCTP_CID_ASCONF_ACK; |
384 | num_ext += 2; | 375 | num_ext += 2; |
385 | } | 376 | } |
386 | 377 | ||
387 | chunksize += sizeof(ext_param) + num_ext; | ||
388 | chunksize += sizeof(aiparam); | 378 | chunksize += sizeof(aiparam); |
389 | 379 | ||
390 | if (asoc->peer.auth_capable) { | 380 | if (asoc->peer.auth_capable) { |
@@ -407,6 +397,9 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, | |||
407 | num_ext += 1; | 397 | num_ext += 1; |
408 | } | 398 | } |
409 | 399 | ||
400 | if (num_ext) | ||
401 | chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; | ||
402 | |||
410 | /* Now allocate and fill out the chunk. */ | 403 | /* Now allocate and fill out the chunk. */ |
411 | retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); | 404 | retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); |
412 | if (!retval) | 405 | if (!retval) |
@@ -428,7 +421,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, | |||
428 | htons(sizeof(sctp_supported_ext_param_t) + num_ext); | 421 | htons(sizeof(sctp_supported_ext_param_t) + num_ext); |
429 | sctp_addto_chunk(retval, sizeof(sctp_supported_ext_param_t), | 422 | sctp_addto_chunk(retval, sizeof(sctp_supported_ext_param_t), |
430 | &ext_param); | 423 | &ext_param); |
431 | sctp_addto_chunk(retval, num_ext, extensions); | 424 | sctp_addto_param(retval, num_ext, extensions); |
432 | } | 425 | } |
433 | if (asoc->peer.prsctp_capable) | 426 | if (asoc->peer.prsctp_capable) |
434 | sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param); | 427 | sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param); |