diff options
author | Martin Willi <martin@strongswan.org> | 2008-05-23 18:23:17 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2008-05-23 18:23:17 +0000 |
commit | 7624dbf0688b684f6405b62e833743b30c1e5060 (patch) | |
tree | 14ac3fe59bd34004b89e5fa96e42b475a0a721b1 /src/charon/encoding | |
parent | 83d9e870ad781ae8894db4d3d143734b4270c7b5 (diff) | |
download | strongswan-7624dbf0688b684f6405b62e833743b30c1e5060.tar.bz2 strongswan-7624dbf0688b684f6405b62e833743b30c1e5060.tar.xz |
process payload length more strictly
Diffstat (limited to 'src/charon/encoding')
-rw-r--r-- | src/charon/encoding/parser.c | 90 |
1 files changed, 56 insertions, 34 deletions
diff --git a/src/charon/encoding/parser.c b/src/charon/encoding/parser.c index a37087580..d002629b3 100644 --- a/src/charon/encoding/parser.c +++ b/src/charon/encoding/parser.c @@ -685,6 +685,11 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ return PARSE_ERROR; } payload_length = *(u_int16_t*)(output + rule->offset); + if (payload_length < UNKNOWN_PAYLOAD_HEADER_LENGTH) + { + pld->destroy(pld); + return PARSE_ERROR; + } break; } case HEADER_LENGTH: @@ -717,8 +722,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case PROPOSALS: { - size_t proposals_length = payload_length - SA_PAYLOAD_HEADER_LENGTH; - if (this->parse_list(this, rule_number, output + rule->offset, PROPOSAL_SUBSTRUCTURE, proposals_length) != SUCCESS) + if (payload_length < SA_PAYLOAD_HEADER_LENGTH || + this->parse_list(this, rule_number, output + rule->offset, PROPOSAL_SUBSTRUCTURE, + payload_length - SA_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -727,8 +733,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case TRANSFORMS: { - size_t transforms_length = payload_length - spi_size - PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH; - if (this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_SUBSTRUCTURE, transforms_length) != SUCCESS) + if (payload_length < spi_size + PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH || + this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_SUBSTRUCTURE, + payload_length - spi_size - PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -737,8 +744,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case TRANSFORM_ATTRIBUTES: { - size_t transform_a_length = payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH; - if (this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_ATTRIBUTE, transform_a_length) != SUCCESS) + if (payload_length < TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH || + this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_ATTRIBUTE, + payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -747,8 +755,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case CONFIGURATION_ATTRIBUTES: { - size_t configuration_attributes_length = payload_length - CP_PAYLOAD_HEADER_LENGTH; - if (this->parse_list(this, rule_number, output + rule->offset, CONFIGURATION_ATTRIBUTE, configuration_attributes_length) != SUCCESS) + if (payload_length < CP_PAYLOAD_HEADER_LENGTH || + this->parse_list(this, rule_number, output + rule->offset, CONFIGURATION_ATTRIBUTE, + payload_length - CP_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -809,8 +818,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case NONCE_DATA: { - size_t nonce_length = payload_length - NONCE_PAYLOAD_HEADER_LENGTH; - if (this->parse_chunk(this, rule_number, output + rule->offset, nonce_length) != SUCCESS) + if (payload_length < NONCE_PAYLOAD_HEADER_LENGTH || + this->parse_chunk(this, rule_number, output + rule->offset, + payload_length - NONCE_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -819,8 +829,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case ID_DATA: { - size_t data_length = payload_length - ID_PAYLOAD_HEADER_LENGTH; - if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS) + if (payload_length < ID_PAYLOAD_HEADER_LENGTH || + this->parse_chunk(this, rule_number, output + rule->offset, + payload_length - ID_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -829,8 +840,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case AUTH_DATA: { - size_t data_length = payload_length - AUTH_PAYLOAD_HEADER_LENGTH; - if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS) + if (payload_length < AUTH_PAYLOAD_HEADER_LENGTH || + this->parse_chunk(this, rule_number, output + rule->offset, + payload_length - AUTH_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -839,8 +851,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case CERT_DATA: { - size_t data_length = payload_length - CERT_PAYLOAD_HEADER_LENGTH; - if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS) + if (payload_length < CERT_PAYLOAD_HEADER_LENGTH || + this->parse_chunk(this, rule_number, output + rule->offset, + payload_length - CERT_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -849,8 +862,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case CERTREQ_DATA: { - size_t data_length = payload_length - CERTREQ_PAYLOAD_HEADER_LENGTH; - if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS) + if (payload_length < CERTREQ_PAYLOAD_HEADER_LENGTH || + this->parse_chunk(this, rule_number, output + rule->offset, + payload_length - CERTREQ_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -859,8 +873,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case EAP_DATA: { - size_t data_length = payload_length - EAP_PAYLOAD_HEADER_LENGTH; - if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS) + if (payload_length < EAP_PAYLOAD_HEADER_LENGTH || + this->parse_chunk(this, rule_number, output + rule->offset, + payload_length - EAP_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -869,8 +884,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case SPIS: { - size_t data_length = payload_length - DELETE_PAYLOAD_HEADER_LENGTH; - if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS) + if (payload_length < DELETE_PAYLOAD_HEADER_LENGTH || + this->parse_chunk(this, rule_number, output + rule->offset, + payload_length - DELETE_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -879,8 +895,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case VID_DATA: { - size_t data_length = payload_length - VENDOR_ID_PAYLOAD_HEADER_LENGTH; - if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS) + if (payload_length < VENDOR_ID_PAYLOAD_HEADER_LENGTH || + this->parse_chunk(this, rule_number, output + rule->offset, + payload_length - VENDOR_ID_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -899,8 +916,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case KEY_EXCHANGE_DATA: { - size_t keydata_length = payload_length - KE_PAYLOAD_HEADER_LENGTH; - if (this->parse_chunk(this, rule_number, output + rule->offset, keydata_length) != SUCCESS) + if (payload_length < KE_PAYLOAD_HEADER_LENGTH || + this->parse_chunk(this, rule_number, output + rule->offset, + payload_length - KE_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -909,8 +927,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case NOTIFICATION_DATA: { - size_t notify_length = payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size; - if (this->parse_chunk(this, rule_number, output + rule->offset, notify_length) != SUCCESS) + if (payload_length < NOTIFY_PAYLOAD_HEADER_LENGTH + spi_size || + this->parse_chunk(this, rule_number, output + rule->offset, + payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -919,8 +938,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case ENCRYPTED_DATA: { - size_t data_length = payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH; - if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS) + if (payload_length < ENCRYPTION_PAYLOAD_HEADER_LENGTH || + this->parse_chunk(this, rule_number, output + rule->offset, + payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -949,8 +969,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case TRAFFIC_SELECTORS: { - size_t traffic_selectors_length = payload_length - TS_PAYLOAD_HEADER_LENGTH; - if (this->parse_list(this, rule_number, output + rule->offset, TRAFFIC_SELECTOR_SUBSTRUCTURE, traffic_selectors_length) != SUCCESS) + if (payload_length < TS_PAYLOAD_HEADER_LENGTH || + this->parse_list(this, rule_number, output + rule->offset, TRAFFIC_SELECTOR_SUBSTRUCTURE, + payload_length - TS_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; @@ -959,8 +980,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case UNKNOWN_DATA: { - size_t unknown_payload_data_length = payload_length - UNKNOWN_PAYLOAD_HEADER_LENGTH; - if (this->parse_chunk(this, rule_number, output + rule->offset, unknown_payload_data_length) != SUCCESS) + if (payload_length < UNKNOWN_PAYLOAD_HEADER_LENGTH || + this->parse_chunk(this, rule_number, output + rule->offset, + payload_length - UNKNOWN_PAYLOAD_HEADER_LENGTH) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; |