From efe37c1e8419e4dc5ad2cc085d61697c24df6a54 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Sat, 26 Feb 2022 16:09:38 +0900 Subject: [PATCH] [ASN1C] asn.1 issues in NGAP (#1394 from @nkout) mouse07410/asn1c#89 Found when tried to encode NGAP_CauseRadioNetwork_release_due_to_pre_emption mouse07410/asn1c#90 Found when tried to decode messages encoded with newer schema --- lib/asn1c/common/NativeEnumerated_aper.c | 6 +- lib/asn1c/common/OPEN_TYPE.h | 8 ++ lib/asn1c/common/OPEN_TYPE_aper.c | 55 ++++++++++++++ lib/asn1c/common/UTF8String.c | 8 +- lib/asn1c/common/constr_SEQUENCE_aper.c | 5 ++ lib/asn1c/ngap/NGAP_ProtocolExtensionField.c | 2 +- lib/asn1c/support/README.md | 77 +++++++++++++++----- 7 files changed, 133 insertions(+), 28 deletions(-) diff --git a/lib/asn1c/common/NativeEnumerated_aper.c b/lib/asn1c/common/NativeEnumerated_aper.c index 08b4573ca..817a783b6 100644 --- a/lib/asn1c/common/NativeEnumerated_aper.c +++ b/lib/asn1c/common/NativeEnumerated_aper.c @@ -89,7 +89,7 @@ NativeEnumerated_encode_aper(const asn_TYPE_descriptor_t *td, asn_enc_rval_t er = {0,0,0}; long native, value; const asn_per_constraint_t *ct; - int inext = 0; + int inext = 0, range_bits = 1; asn_INTEGER_enum_map_t key; asn_INTEGER_enum_map_t *kf; @@ -126,12 +126,12 @@ NativeEnumerated_encode_aper(const asn_TYPE_descriptor_t *td, if(ct->flags & APC_EXTENSIBLE) { if(per_put_few_bits(po, inext, 1)) ASN__ENCODE_FAILED; - if(inext) ct = 0; + if(inext) range_bits = 0; } else if(inext) { ASN__ENCODE_FAILED; } - if(ct && ct->range_bits >= 0) { + if(range_bits && ct && ct->range_bits >= 0) { if(per_put_few_bits(po, value, ct->range_bits)) ASN__ENCODE_FAILED; ASN__ENCODED_OK(er); diff --git a/lib/asn1c/common/OPEN_TYPE.h b/lib/asn1c/common/OPEN_TYPE.h index b9334d28b..70681db92 100644 --- a/lib/asn1c/common/OPEN_TYPE.h +++ b/lib/asn1c/common/OPEN_TYPE.h @@ -94,6 +94,14 @@ asn_enc_rval_t OPEN_TYPE_encode_aper( const asn_TYPE_descriptor_t *type_descriptor, const asn_per_constraints_t *constraints, const void *struct_ptr, asn_per_outp_t *per_output); + +int OPEN_TYPE_aper_is_unknown_type( + const asn_TYPE_descriptor_t *td, + void *sptr, + const asn_TYPE_member_t *elm); + +asn_dec_rval_t OPEN_TYPE_aper_unknown_type_discard_bytes( + asn_per_data_t *pd); #endif /* !defined(ASN_DISABLE_APER_SUPPORT) */ extern asn_TYPE_operation_t asn_OP_OPEN_TYPE; diff --git a/lib/asn1c/common/OPEN_TYPE_aper.c b/lib/asn1c/common/OPEN_TYPE_aper.c index 215f67c87..a1a8e19cd 100644 --- a/lib/asn1c/common/OPEN_TYPE_aper.c +++ b/lib/asn1c/common/OPEN_TYPE_aper.c @@ -117,3 +117,58 @@ OPEN_TYPE_encode_aper(const asn_TYPE_descriptor_t *td, er.encoded = 0; ASN__ENCODED_OK(er); } + + +int OPEN_TYPE_aper_is_unknown_type(const asn_TYPE_descriptor_t *td, void *sptr, const asn_TYPE_member_t *elm) { + asn_type_selector_result_t selected; + + if(!elm->type_selector) { + return 1; + } + else { + selected = elm->type_selector(td, sptr); + if(!selected.presence_index) { + return 1; + } + } + return 0; +} + +asn_dec_rval_t +OPEN_TYPE_aper_unknown_type_discard_bytes (asn_per_data_t *pd) { +#define ASN_DUMMY_BYTES 256 + unsigned char dummy[ASN_DUMMY_BYTES], *dummy_ptr = NULL; + ssize_t bytes; + int repeat; + asn_dec_rval_t rv; + + rv.consumed = 0; + rv.code = RC_FAIL; + + do { + bytes = aper_get_length(pd, -1, -1, &repeat); + if (bytes > 10 * ASN_DUMMY_BYTES) + { + return rv; + } + else if (bytes > ASN_DUMMY_BYTES) + { + dummy_ptr = CALLOC(1, bytes); + if (!dummy_ptr) + return rv; + } + + per_get_many_bits(pd, (dummy_ptr ? dummy_ptr : dummy), 0, bytes << 3); + + if (dummy_ptr) + { + FREEMEM(dummy_ptr); + dummy_ptr = NULL; + } + } while (repeat); + + rv.code = RC_OK; + return rv; +#undef ASN_DUMMY_BYTES +} + diff --git a/lib/asn1c/common/UTF8String.c b/lib/asn1c/common/UTF8String.c index a24b6afea..26343357f 100644 --- a/lib/asn1c/common/UTF8String.c +++ b/lib/asn1c/common/UTF8String.c @@ -151,10 +151,10 @@ UTF8String_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, static ssize_t UTF8String__process(const UTF8String_t *st, uint32_t *dst, size_t dstlen) { - size_t length; - uint8_t *buf = st->buf; - uint8_t *end = buf + st->size; - uint32_t *dstend = dst + dstlen; + size_t length = 0; + uint8_t *buf = (st == NULL)? NULL : st->buf; + uint8_t *end = (buf == NULL)? NULL : buf + st->size; + uint32_t *dstend = (dst == NULL)? NULL : dst + dstlen; for(length = 0; buf < end; length++) { int ch = *buf; diff --git a/lib/asn1c/common/constr_SEQUENCE_aper.c b/lib/asn1c/common/constr_SEQUENCE_aper.c index 6c3dfe8d2..5d05921a5 100644 --- a/lib/asn1c/common/constr_SEQUENCE_aper.c +++ b/lib/asn1c/common/constr_SEQUENCE_aper.c @@ -130,6 +130,11 @@ SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name); if(elm->flags & ATF_OPEN_TYPE) { + if (OPEN_TYPE_aper_is_unknown_type(td, st, elm)) { + rv = OPEN_TYPE_aper_unknown_type_discard_bytes(pd); + FREEMEM(opres); + return rv; + } rv = OPEN_TYPE_aper_get(opt_codec_ctx, td, st, elm, pd); } else { rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type, diff --git a/lib/asn1c/ngap/NGAP_ProtocolExtensionField.c b/lib/asn1c/ngap/NGAP_ProtocolExtensionField.c index 9437b2983..aa494bd6f 100644 --- a/lib/asn1c/ngap/NGAP_ProtocolExtensionField.c +++ b/lib/asn1c/ngap/NGAP_ProtocolExtensionField.c @@ -49420,7 +49420,7 @@ static asn_TYPE_member_t asn_MBR_NGAP_extensionValue_648[] = { 0, #endif /* !defined(ASN_DISABLE_OER_SUPPORT) */ #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) -#if 0 +#if 0 /* modified by acetcom */ &asn_PER_memb_NGAP_OCTET_STRING_CONTAINING_PDUSessionResourceReleaseResponseTransfer__constr_47, #else 0, diff --git a/lib/asn1c/support/README.md b/lib/asn1c/support/README.md index 8e92389db..055bdc674 100644 --- a/lib/asn1c/support/README.md +++ b/lib/asn1c/support/README.md @@ -1,15 +1,17 @@ Use mounse07410(vlm_master) git's fork for asn1c -commit dcf963c0e43196057a97feac16421fe79dc7d943 (HEAD -> vlm_master, origin/vlm_master, origin/HEAD) -Merge: b33a84f9 c35ebd33 -Author: Mouse -Date: Sun Nov 1 08:58:12 2020 -0500 +commit c098de2086633d2027f1d117092541d8482c1c96 (HEAD -> vlm_master, origin/vlm_master, origin/HEAD) +Author: Nikolaos Koutsianas +Date: Fri Feb 25 13:18:01 2022 +0200 + + aper decoder can ignore unknown open types in a sequence and continue with next ones + =========================================== user@host ~/Documents/git/my$ \ git clone https://github.com/mouse07410/asn1c.git user@host ~/Documents/git/my$ \ - git checkout 8282f80bc89cc773f9432cde56398a36f2683511 + git checkout git checkout c098de2086633d2027f1d117092541d8482c1c96 OR @@ -175,24 +177,59 @@ Check common file user@host ~/Documents/git/open5gs/lib/asn1c/common$ \ git diff asn_internal.h diff --git a/lib/asn1c/common/asn_internal.h b/lib/asn1c/common/asn_internal.h -index 71397a62..0b673a46 100644 ---- a/lib/asn1c/common/asn_internal.h -+++ b/lib/asn1c/common/asn_internal.h -@@ -34,18 +34,11 @@ extern "C" { - #define ASN1C_ENVIRONMENT_VERSION 923 /* Compile-time version */ - int get_asn1c_environment_version(void); /* Run-time version */ +diff -u asn_internal.h ~/asn_internal.h +--- asn_internal.h 2022-02-26 15:48:33.431509100 +0900 ++++ /home/acetcom/asn_internal.h 2022-02-26 15:43:00.890972555 +0900 +@@ -34,10 +34,53 @@ + #define ASN1C_ENVIRONMENT_VERSION 923 /* Compile-time version */ + int get_asn1c_environment_version(void); /* Run-time version */ +#if 0 /* modified by acetcom */ -+#define CALLOC(nmemb, size) calloc(nmemb, size) -+#define MALLOC(size) malloc(size) -+#define REALLOC(oldptr, size) realloc(oldptr, size) -+#define FREEMEM(ptr) free(ptr) + #define CALLOC(nmemb, size) calloc(nmemb, size) + #define MALLOC(size) malloc(size) + #define REALLOC(oldptr, size) realloc(oldptr, size) + #define FREEMEM(ptr) free(ptr) +#else - #include "ogs-core.h" - #define CALLOC(nmemb, size) ogs_calloc(nmemb, size) - #define MALLOC(size) ogs_malloc(size) - #define REALLOC(oldptr, size) ogs_realloc(oldptr, size) - #define FREEMEM(ptr) ogs_free(ptr) ++#include "ogs-core.h" ++ ++static ogs_inline void *ogs_asn_malloc(size_t size, const char *file_line) ++{ ++ void *ptr = ogs_malloc(size); ++ if (!ptr) { ++ ogs_fatal("asn_malloc() failed in `%s`", file_line); ++ ogs_assert_if_reached(); ++ } ++ ++ return ptr; ++} ++static ogs_inline void *ogs_asn_calloc( ++ size_t nmemb, size_t size, const char *file_line) ++{ ++ void *ptr = ogs_calloc(nmemb, size); ++ if (!ptr) { ++ ogs_fatal("asn_calloc() failed in `%s`", file_line); ++ ogs_assert_if_reached(); ++ } ++ ++ return ptr; ++} ++static ogs_inline void *ogs_asn_realloc( ++ void *oldptr, size_t size, const char *file_line) ++{ ++ void *ptr = ogs_realloc(oldptr, size); ++ if (!ptr) { ++ ogs_fatal("asn_realloc() failed in `%s`", file_line); ++ ogs_assert_if_reached(); ++ } ++ ++ return ptr; ++} ++ ++#define CALLOC(nmemb, size) ogs_asn_calloc(nmemb, size, OGS_FILE_LINE) ++#define MALLOC(size) ogs_asn_malloc(size, OGS_FILE_LINE) ++#define REALLOC(oldptr, size) ogs_asn_realloc(oldptr, size, OGS_FILE_LINE) ++#define FREEMEM(ptr) ogs_free(ptr) ++ +#endif #define asn_debug_indent 0