From 922dac1a34c5496f1c449dd3c397358a8e1e74ef Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Thu, 28 Sep 2017 13:23:15 +0200 Subject: [PATCH] - MMS: fixed potential memory leak in asn1 code that can be caused by malformed MMS messages --- src/mms/iso_mms/asn1c/constr_SEQUENCE.c | 6 +++--- src/mms/iso_mms/asn1c/constr_SET_OF.c | 11 +++++++++++ .../iso_mms/server/mms_named_variable_list_service.c | 7 ++++--- src/mms/iso_mms/server/mms_read_service.c | 3 ++- src/mms/iso_mms/server/mms_write_service.c | 2 +- 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/mms/iso_mms/asn1c/constr_SEQUENCE.c b/src/mms/iso_mms/asn1c/constr_SEQUENCE.c index 72043f5..35aec84 100644 --- a/src/mms/iso_mms/asn1c/constr_SEQUENCE.c +++ b/src/mms/iso_mms/asn1c/constr_SEQUENCE.c @@ -33,7 +33,7 @@ #undef ADVANCE #define ADVANCE(num_bytes) do { \ size_t num = num_bytes; \ - ptr = ((const char *)ptr) + num;\ + ptr = ((const char *)ptr) + num; \ size -= num; \ if(ctx->left >= 0) \ ctx->left -= num; \ @@ -328,11 +328,12 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, * or an extension (...), * or an end of the indefinite-length structure. */ - if(!IN_EXTENSION_GROUP(specs, edx)) { + if(!IN_EXTENSION_GROUP(specs, edx + elements[edx].optional)) { RETURN(RC_FAIL); } else { /* Skip this tag */ ssize_t skip; + edx += elements[edx].optional; skip = ber_skip_length(opt_codec_ctx, BER_TLV_CONSTRUCTED(ptr), @@ -1135,7 +1136,6 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td, er.encoded = 0; - ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name); if(specs->ext_before >= 0) _ASN_ENCODE_FAILED; /* We don't encode extensions yet */ diff --git a/src/mms/iso_mms/asn1c/constr_SET_OF.c b/src/mms/iso_mms/asn1c/constr_SET_OF.c index 7e9e3f6..e183de4 100644 --- a/src/mms/iso_mms/asn1c/constr_SET_OF.c +++ b/src/mms/iso_mms/asn1c/constr_SET_OF.c @@ -213,6 +213,8 @@ SET_OF_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } /* Fall through */ case RC_FAIL: /* Fatal error */ + ASN_STRUCT_FREE(*elm->type, ctx->ptr); + ctx->ptr = 0; RETURN(RC_FAIL); } /* switch(rval) */ @@ -764,8 +766,10 @@ SET_OF_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, void SET_OF_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) { if(td && ptr) { + asn_SET_OF_specifics_t *specs; asn_TYPE_member_t *elm = td->elements; asn_anonymous_set_ *list = _A_SET_FROM_VOID(ptr); + asn_struct_ctx_t *ctx; /* Decoder context */ int i; /* @@ -781,6 +785,13 @@ SET_OF_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) { asn_set_empty(list); /* Remove (list->array) */ + specs = (asn_SET_OF_specifics_t *)td->specifics; + ctx = (asn_struct_ctx_t *)((char *)ptr + specs->ctx_offset); + if(ctx->ptr) { + ASN_STRUCT_FREE(*elm->type, ctx->ptr); + ctx->ptr = 0; + } + if(!contents_only) { FREEMEM(ptr); } diff --git a/src/mms/iso_mms/server/mms_named_variable_list_service.c b/src/mms/iso_mms/server/mms_named_variable_list_service.c index 2a48b02..c56f6ca 100644 --- a/src/mms/iso_mms/server/mms_named_variable_list_service.c +++ b/src/mms/iso_mms/server/mms_named_variable_list_service.c @@ -233,9 +233,10 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection, mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED); } +exit_function: + asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); -exit_function: return; } @@ -420,7 +421,7 @@ mmsServer_handleDefineNamedVariableListRequest( if (rval.code != RC_OK) { mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); - goto exit_function; + goto exit_free_struct; } request = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.defineNamedVariableList); @@ -666,7 +667,7 @@ mmsServer_handleGetNamedVariableListAttributesRequest( if (rval.code != RC_OK) { mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); - return; + goto exit_function; } if (request->present == ObjectName_PR_domainspecific) { diff --git a/src/mms/iso_mms/server/mms_read_service.c b/src/mms/iso_mms/server/mms_read_service.c index 6f8f0b3..7d69193 100644 --- a/src/mms/iso_mms/server/mms_read_service.c +++ b/src/mms/iso_mms/server/mms_read_service.c @@ -747,7 +747,7 @@ mmsServer_handleReadRequest( if (rval.code != RC_OK) { mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); - return; + goto exit_function; } request = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.read); @@ -764,6 +764,7 @@ mmsServer_handleReadRequest( mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED); } +exit_function: asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); } diff --git a/src/mms/iso_mms/server/mms_write_service.c b/src/mms/iso_mms/server/mms_write_service.c index c616f4d..41c0a70 100644 --- a/src/mms/iso_mms/server/mms_write_service.c +++ b/src/mms/iso_mms/server/mms_write_service.c @@ -481,7 +481,7 @@ mmsServer_handleWriteRequest( if (rval.code != RC_OK) { mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); - return; + goto exit_function; } WriteRequest_t* writeRequest = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.write);