diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 5f753b208de5a02f77b315fe1c76ada2bfa71660..bae3af88fe6a50547ca96344444fd613754a23df 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -1185,7 +1185,8 @@ dup sctp_generic_chunk_spec : CHUNK '[' opt_chunk_type ',' opt_flags ',' opt_len ',' opt_val ']' { - if (($7 != -1) && ($7 < sizeof(struct sctp_chunk))) { + if (($7 != -1) && + (!is_valid_u16($7) || ($7 < sizeof(struct sctp_chunk)))) { semantic_error("length value out of range"); } if (($7 != -1) && ($9 != NULL) && @@ -1200,7 +1201,8 @@ sctp_generic_chunk_spec sctp_data_chunk_spec : DATA '[' opt_data_flags ',' opt_len ',' opt_tsn ',' opt_sid ',' opt_ssn ',' opt_ppid ']' { - if (($5 != -1) && ($5 < sizeof(struct sctp_data_chunk))) { + if (($5 != -1) && + (!is_valid_u16($5) || ($5 < sizeof(struct sctp_data_chunk)))) { semantic_error("length value out of range"); } $$ = sctp_data_chunk_new($3, $5, $7, $9, $11, $13); @@ -1253,6 +1255,10 @@ sctp_error_chunk_spec sctp_cookie_echo_chunk_spec : COOKIE_ECHO '[' opt_flags ',' opt_len ',' VAL '=' ELLIPSIS ']' { + if (($5 != -1) && + (!is_valid_u16($5) || ($5 < sizeof(struct sctp_cookie_echo_chunk)))) { + semantic_error("length value out of range"); + } $$ = sctp_cookie_echo_chunk_new($3, $5, NULL); } @@ -1278,6 +1284,10 @@ sctp_shutdown_complete_chunk_spec sctp_pad_chunk_spec : PAD '[' opt_flags ',' opt_len ',' VAL '=' ELLIPSIS ']' { + if (($5 != -1) && + (!is_valid_u16($5) || ($5 < sizeof(struct sctp_pad_chunk)))) { + semantic_error("length value out of range"); + } $$ = sctp_pad_chunk_new($3, $5, NULL); } @@ -1326,7 +1336,8 @@ opt_parameter_type sctp_generic_parameter_spec : PARAMETER '[' opt_parameter_type ',' opt_len ',' opt_val ']' { - if (($5 != -1) && ($5 < sizeof(struct sctp_parameter))) { + if (($5 != -1) && + (!is_valid_u16($5) || ($5 < sizeof(struct sctp_parameter)))) { semantic_error("length value out of range"); } if (($5 != -1) && ($7 != NULL) && @@ -1343,15 +1354,19 @@ sctp_heartbeat_information_parameter_spec : HEARTBEAT_INFORMATION '[' ELLIPSIS ']' { $$ = sctp_heartbeat_information_parameter_new(-1, NULL); } -| HEARTBEAT_INFORMATION '[' LEN '=' ELLIPSIS ',' VAL '=' ELLIPSIS ']' { - $$ = sctp_heartbeat_information_parameter_new(-1, NULL); -} -| HEARTBEAT_INFORMATION '[' LEN '=' INTEGER ',' VAL '=' ELLIPSIS ']' { - if (($5 < sizeof(struct sctp_heartbeat_information_parameter)) || - !is_valid_u16($5)) { - semantic_error("len value out of range"); +| HEARTBEAT_INFORMATION '[' opt_len ',' opt_val ']' { + if (($3 != -1) && + (!is_valid_u16($3) || ($3 < sizeof(struct sctp_heartbeat_information_parameter)))) { + semantic_error("length value out of range"); + } + if (($3 != -1) && ($5 != NULL) && + ($3 != sizeof(struct sctp_heartbeat_information_parameter) + $5->nr_entries)) { + semantic_error("length value incompatible with val"); + } + if (($3 == -1) && ($5 != NULL)) { + semantic_error("length needs to be specified"); } - $$ = sctp_heartbeat_information_parameter_new($5, NULL); + $$ = sctp_heartbeat_information_parameter_new($3, $5); } sctp_ipv4_address_parameter_spec @@ -1517,7 +1532,8 @@ opt_cause_code sctp_generic_cause_spec : CAUSE '[' opt_cause_code ',' opt_len ',' opt_info ']' { - if (($5 != -1) && ($5 < sizeof(struct sctp_cause))) { + if (($5 != -1) && + (!is_valid_u16($5) || ($5 < sizeof(struct sctp_cause)))) { semantic_error("length value out of range"); } if (($5 != -1) && ($7 != NULL) && diff --git a/gtests/net/packetdrill/sctp_packet.c b/gtests/net/packetdrill/sctp_packet.c index 8a7280749969993e4970f29819034e6ea457e290..08df4f48bfd2b64550a24bd58341dd65c6f9f8f7 100644 --- a/gtests/net/packetdrill/sctp_packet.c +++ b/gtests/net/packetdrill/sctp_packet.c @@ -945,7 +945,9 @@ sctp_cookie_echo_chunk_new(s64 flgs, s64 len, u8* cookie) u32 flags; u16 chunk_length, cookie_length, padding_length; - assert((len == -1) || is_valid_u16(len)); + assert((len == -1) || + (is_valid_u16(len) && + len >= sizeof(struct sctp_cookie_echo_chunk))); assert((len != -1) || (cookie == NULL)); flags = 0; if (len == -1) { @@ -1247,41 +1249,9 @@ sctp_generic_parameter_new(s64 type, s64 len, struct sctp_byte_list *bytes) } struct sctp_parameter_list_item * -sctp_heartbeat_information_parameter_new(s64 len, u8 *information) +sctp_heartbeat_information_parameter_new(s64 len, struct sctp_byte_list *bytes) { - struct sctp_heartbeat_information_parameter *parameter; - u32 flags; - u16 parameter_length, information_length, padding_length; - - assert((len == -1) || is_valid_u16(len)); - assert((len != -1) || (information == NULL)); - flags = 0; - if (len == -1) { - information_length = 0; - flags |= FLAG_PARAMETER_LENGTH_NOCHECK; - } else { - assert(len <= MAX_SCTP_PARAMETER_BYTES - sizeof(struct sctp_heartbeat_information_parameter)); - information_length = len - sizeof(struct sctp_heartbeat_information_parameter); - } - parameter_length = information_length + sizeof(struct sctp_heartbeat_information_parameter); - padding_length = parameter_length % 4; - if (padding_length > 0) { - padding_length = 4 - padding_length; - } - parameter = malloc(parameter_length + padding_length); - assert(parameter != NULL); - parameter->type = htons(SCTP_HEARTBEAT_INFORMATION_PARAMETER_TYPE); - parameter->length = htons(parameter_length); - if (information != NULL) { - memcpy(parameter->information, information, information_length); - } else { - flags |= FLAG_PARAMETER_VALUE_NOCHECK; - memset(parameter->information, 'A', information_length); - } - /* Clear the padding */ - memset(parameter->information + information_length, 0, padding_length); - return sctp_parameter_list_item_new((struct sctp_parameter *)parameter, - parameter_length, flags); + return sctp_generic_parameter_new(SCTP_HEARTBEAT_INFORMATION_PARAMETER_TYPE, len,bytes); } struct sctp_parameter_list_item * diff --git a/gtests/net/packetdrill/sctp_packet.h b/gtests/net/packetdrill/sctp_packet.h index 4207111139aaa9dd03eafc0a98cb913215a651f2..7e2b170a58f4bd4925eac539b5868a8f8e2c0594 100644 --- a/gtests/net/packetdrill/sctp_packet.h +++ b/gtests/net/packetdrill/sctp_packet.h @@ -300,7 +300,7 @@ struct sctp_parameter_list_item * sctp_generic_parameter_new(s64 type, s64 len, struct sctp_byte_list *bytes); struct sctp_parameter_list_item * -sctp_heartbeat_information_parameter_new(s64 len, u8 *information); +sctp_heartbeat_information_parameter_new(s64 len, struct sctp_byte_list *bytes); struct sctp_parameter_list_item * sctp_ipv4_address_parameter_new(struct in_addr *addr);