aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2009-11-23 15:53:56 -0500
committerVlad Yasevich <vladislav.yasevich@hp.com>2009-11-23 15:53:56 -0500
commit6383cfb3ed3c5c0bea06da0099c219ef4237ecf5 (patch)
treee3bfb43500b664c5a572d0a9456d7e7ec4f7aeab /net/sctp
parentb93d6471748de2ce02cc24774b774deb306a57a8 (diff)
sctp: Fix malformed "Invalid Stream Identifier" error
The "Invalid Stream Identifier" error has a 16 bit reserved field at the end, thus making the parameter length be 8 bytes. We've never supplied that reserved field making wireshark tag the packet as malformed. Reported-by: Chris Dischino <cdischino@sonusnet.com> Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/sm_make_chunk.c13
-rw-r--r--net/sctp/sm_statefuns.c13
2 files changed, 17 insertions, 9 deletions
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 9d881a61ac02..9e732916b671 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -987,7 +987,10 @@ static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
987 987
988 target = skb_put(chunk->skb, len); 988 target = skb_put(chunk->skb, len);
989 989
990 memcpy(target, data, len); 990 if (data)
991 memcpy(target, data, len);
992 else
993 memset(target, 0, len);
991 994
992 /* Adjust the chunk length field. */ 995 /* Adjust the chunk length field. */
993 chunk->chunk_hdr->length = htons(chunklen + len); 996 chunk->chunk_hdr->length = htons(chunklen + len);
@@ -1129,16 +1132,18 @@ nodata:
1129struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc, 1132struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc,
1130 const struct sctp_chunk *chunk, 1133 const struct sctp_chunk *chunk,
1131 __be16 cause_code, const void *payload, 1134 __be16 cause_code, const void *payload,
1132 size_t paylen) 1135 size_t paylen, size_t reserve_tail)
1133{ 1136{
1134 struct sctp_chunk *retval; 1137 struct sctp_chunk *retval;
1135 1138
1136 retval = sctp_make_op_error_space(asoc, chunk, paylen); 1139 retval = sctp_make_op_error_space(asoc, chunk, paylen + reserve_tail);
1137 if (!retval) 1140 if (!retval)
1138 goto nodata; 1141 goto nodata;
1139 1142
1140 sctp_init_cause(retval, cause_code, paylen); 1143 sctp_init_cause(retval, cause_code, paylen + reserve_tail);
1141 sctp_addto_chunk(retval, paylen, payload); 1144 sctp_addto_chunk(retval, paylen, payload);
1145 if (reserve_tail)
1146 sctp_addto_param(retval, reserve_tail, NULL);
1142 1147
1143nodata: 1148nodata:
1144 return retval; 1149 return retval;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 8ee24c9dc7e9..16a603527df2 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -1720,7 +1720,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
1720 1720
1721 err = sctp_make_op_error(asoc, chunk, 1721 err = sctp_make_op_error(asoc, chunk,
1722 SCTP_ERROR_COOKIE_IN_SHUTDOWN, 1722 SCTP_ERROR_COOKIE_IN_SHUTDOWN,
1723 NULL, 0); 1723 NULL, 0, 0);
1724 if (err) 1724 if (err)
1725 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, 1725 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
1726 SCTP_CHUNK(err)); 1726 SCTP_CHUNK(err));
@@ -3977,7 +3977,7 @@ sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,
3977 err_chunk = sctp_make_op_error(asoc, chunk, 3977 err_chunk = sctp_make_op_error(asoc, chunk,
3978 SCTP_ERROR_UNSUP_HMAC, 3978 SCTP_ERROR_UNSUP_HMAC,
3979 &auth_hdr->hmac_id, 3979 &auth_hdr->hmac_id,
3980 sizeof(__u16)); 3980 sizeof(__u16), 0);
3981 if (err_chunk) { 3981 if (err_chunk) {
3982 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, 3982 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
3983 SCTP_CHUNK(err_chunk)); 3983 SCTP_CHUNK(err_chunk));
@@ -4069,7 +4069,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
4069 hdr = unk_chunk->chunk_hdr; 4069 hdr = unk_chunk->chunk_hdr;
4070 err_chunk = sctp_make_op_error(asoc, unk_chunk, 4070 err_chunk = sctp_make_op_error(asoc, unk_chunk,
4071 SCTP_ERROR_UNKNOWN_CHUNK, hdr, 4071 SCTP_ERROR_UNKNOWN_CHUNK, hdr,
4072 WORD_ROUND(ntohs(hdr->length))); 4072 WORD_ROUND(ntohs(hdr->length)),
4073 0);
4073 if (err_chunk) { 4074 if (err_chunk) {
4074 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, 4075 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
4075 SCTP_CHUNK(err_chunk)); 4076 SCTP_CHUNK(err_chunk));
@@ -4088,7 +4089,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
4088 hdr = unk_chunk->chunk_hdr; 4089 hdr = unk_chunk->chunk_hdr;
4089 err_chunk = sctp_make_op_error(asoc, unk_chunk, 4090 err_chunk = sctp_make_op_error(asoc, unk_chunk,
4090 SCTP_ERROR_UNKNOWN_CHUNK, hdr, 4091 SCTP_ERROR_UNKNOWN_CHUNK, hdr,
4091 WORD_ROUND(ntohs(hdr->length))); 4092 WORD_ROUND(ntohs(hdr->length)),
4093 0);
4092 if (err_chunk) { 4094 if (err_chunk) {
4093 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, 4095 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
4094 SCTP_CHUNK(err_chunk)); 4096 SCTP_CHUNK(err_chunk));
@@ -6052,7 +6054,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
6052 6054
6053 err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM, 6055 err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM,
6054 &data_hdr->stream, 6056 &data_hdr->stream,
6055 sizeof(data_hdr->stream)); 6057 sizeof(data_hdr->stream),
6058 sizeof(u16));
6056 if (err) 6059 if (err)
6057 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, 6060 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
6058 SCTP_CHUNK(err)); 6061 SCTP_CHUNK(err));