diff --git a/0001-Fix-endless-loop-in-_asn1_check_identifier.patch b/0001-Fix-endless-loop-in-_asn1_check_identifier.patch new file mode 100644 index 0000000000000000000000000000000000000000..89c2a41f55af25ec833f8f0ed24889de5a43b296 --- /dev/null +++ b/0001-Fix-endless-loop-in-_asn1_check_identifier.patch @@ -0,0 +1,29 @@ +From c32f0f1d3ed15e0286bc6e1757ccbe3b9f8c9cda Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tim=20R=C3=BChsen?= +Date: Fri, 19 Jul 2019 13:16:27 +0200 +Subject: [PATCH] Fix endless loop in _asn1_check_identifier() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Tim Rühsen +--- + lib/parser_aux.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/lib/parser_aux.c b/lib/parser_aux.c +index b182948..095204e 100644 +--- a/lib/parser_aux.c ++++ b/lib/parser_aux.c +@@ -1029,7 +1029,7 @@ _asn1_check_identifier (asn1_node_const node) + p = p->right; + else + { +- while (1) ++ while (p) + { + p = _asn1_find_up (p); + if (p == node) +-- +1.8.3.1 + diff --git a/0002-_asn1_expand_object_id-Limit-recursion.patch b/0002-_asn1_expand_object_id-Limit-recursion.patch new file mode 100644 index 0000000000000000000000000000000000000000..02e194fc55fc3875a0899863f66a58745daf22f3 --- /dev/null +++ b/0002-_asn1_expand_object_id-Limit-recursion.patch @@ -0,0 +1,203 @@ +From 1213efef01cd0e58dff341e126b1af180cc27a1e Mon Sep 17 00:00:00 2001 +From: Mike Gorse +Date: Thu, 11 Apr 2019 11:14:58 -0500 +Subject: [PATCH] _asn1_expand_object_id: Limit recursion + +Resolves #4 + +Signed-off-by: Mike Gorse +Signed-off-by: Nikos Mavrogiannopoulos +--- + lib/ASN1.c | 8 +++++++- + lib/ASN1.y | 5 ++++- + lib/errors.c | 1 + + lib/libtasn1.h | 1 + + lib/parser_aux.c | 31 ++++++++++++++++++++++++++++--- + lib/parser_aux.h | 1 + + lib/structure.c | 2 +- + 7 files changed, 43 insertions(+), 6 deletions(-) + +diff --git a/lib/ASN1.c b/lib/ASN1.c +index 586dcca..47074f0 100644 +--- a/lib/ASN1.c ++++ b/lib/ASN1.c +@@ -2811,7 +2811,12 @@ asn1_parser2tree (const char *file, asn1_node * definitions, + /* Convert into DER coding the value assign to INTEGER constants */ + _asn1_change_integer_value (p_tree); + /* Expand the IDs of OBJECT IDENTIFIER constants */ +- _asn1_expand_object_id (p_tree); ++ result_parse = _asn1_expand_object_id (p_tree); ++ if (result_parse != ASN1_SUCCESS) ++ { ++ _asn1_delete_list_and_nodes (); ++ goto error; ++ } + + *definitions = p_tree; + } +@@ -2824,6 +2829,7 @@ asn1_parser2tree (const char *file, asn1_node * definitions, + _asn1_delete_list_and_nodes (); + } + ++ error: + _asn1_create_errorDescription (result_parse, error_desc); + + return result_parse; +diff --git a/lib/ASN1.y b/lib/ASN1.y +index 534a9f1..0b81b5b 100644 +--- a/lib/ASN1.y ++++ b/lib/ASN1.y +@@ -701,7 +701,9 @@ asn1_parser2tree (const char *file, asn1_node * definitions, + /* Convert into DER coding the value assign to INTEGER constants */ + _asn1_change_integer_value (p_tree); + /* Expand the IDs of OBJECT IDENTIFIER constants */ +- _asn1_expand_object_id (p_tree); ++ result_parse = _asn1_expand_object_id (p_tree); ++ if (result_parse != ASN1_SUCCESS) ++ goto error; + + *definitions = p_tree; + } +@@ -714,6 +716,7 @@ asn1_parser2tree (const char *file, asn1_node * definitions, + _asn1_delete_list_and_nodes (); + } + ++ error: + _asn1_create_errorDescription (result_parse, error_desc); + + return result_parse; +diff --git a/lib/errors.c b/lib/errors.c +index fef45ae..cee74da 100644 +--- a/lib/errors.c ++++ b/lib/errors.c +@@ -53,6 +53,7 @@ static const libtasn1_error_entry error_algorithms[] = { + LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR), + LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY), + LIBTASN1_ERROR_ENTRY (ASN1_TIME_ENCODING_ERROR), ++ LIBTASN1_ERROR_ENTRY (ASN1_RECURSION), + {0, 0} + }; + +diff --git a/lib/libtasn1.h b/lib/libtasn1.h +index ea26b78..8c757d6 100644 +--- a/lib/libtasn1.h ++++ b/lib/libtasn1.h +@@ -79,6 +79,7 @@ extern "C" + #define ASN1_ARRAY_ERROR 16 + #define ASN1_ELEMENT_NOT_EMPTY 17 + #define ASN1_TIME_ENCODING_ERROR 18 ++#define ASN1_RECURSION 19 + + /*************************************/ + /* Constants used in asn1_visit_tree */ +diff --git a/lib/parser_aux.c b/lib/parser_aux.c +index 7d7ccf3..e5fecbd 100644 +--- a/lib/parser_aux.c ++++ b/lib/parser_aux.c +@@ -517,6 +517,23 @@ _asn1_find_up (asn1_node node) + } + + /******************************************************************/ ++/* Function : _asn1_delete_node_from_list */ ++/* Description: deletes the list element given */ ++/******************************************************************/ ++static void ++_asn1_delete_node_from_list (asn1_node node) ++{ ++ list_type *p = firstElement; ++ ++ while (p) ++ { ++ if (p->node == node) ++ p->node = NULL; ++ p = p->next; ++ } ++} ++ ++/******************************************************************/ + /* Function : _asn1_delete_list */ + /* Description: deletes the list elements (not the elements */ + /* pointed by them). */ +@@ -667,15 +684,15 @@ _asn1_change_integer_value (asn1_node node) + /* Parameters: */ + /* node: root of an ASN1 element. */ + /* Return: */ +-/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ +-/* otherwise ASN1_SUCCESS */ ++/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ ++/* otherwise ASN1_SUCCESS */ + /******************************************************************/ + int + _asn1_expand_object_id (asn1_node node) + { + asn1_node p, p2, p3, p4, p5; + char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1]; +- int move, tlen; ++ int move, tlen, tries; + + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; +@@ -684,6 +701,7 @@ _asn1_expand_object_id (asn1_node node) + + p = node; + move = DOWN; ++ tries = 0; + + while (!((p == node) && (move == UP))) + { +@@ -707,6 +725,7 @@ _asn1_expand_object_id (asn1_node node) + || !(p3->type & CONST_ASSIGN)) + return ASN1_ELEMENT_NOT_FOUND; + _asn1_set_down (p, p2->right); ++ _asn1_delete_node_from_list(p2); + _asn1_remove_node (p2, 0); + p2 = p; + p4 = p3->down; +@@ -738,6 +757,11 @@ _asn1_expand_object_id (asn1_node node) + p4 = p4->right; + } + move = DOWN; ++ ++ tries++; ++ if (tries >= EXPAND_OBJECT_ID_MAX_RECURSION) ++ return ASN1_RECURSION; ++ + continue; + } + } +@@ -747,6 +771,7 @@ _asn1_expand_object_id (asn1_node node) + else + move = RIGHT; + ++ tries = 0; + if (move == DOWN) + { + if (p->down) +diff --git a/lib/parser_aux.h b/lib/parser_aux.h +index 9f91833..bb05ae8 100644 +--- a/lib/parser_aux.h ++++ b/lib/parser_aux.h +@@ -60,6 +60,7 @@ asn1_node _asn1_find_up (asn1_node node); + + int _asn1_change_integer_value (asn1_node node); + ++#define EXPAND_OBJECT_ID_MAX_RECURSION 16 + int _asn1_expand_object_id (asn1_node node); + + int _asn1_type_set_config (asn1_node node); +diff --git a/lib/structure.c b/lib/structure.c +index 01715b1..f6a93fa 100644 +--- a/lib/structure.c ++++ b/lib/structure.c +@@ -245,7 +245,7 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + if (result == ASN1_SUCCESS) + { + _asn1_change_integer_value (*definitions); +- _asn1_expand_object_id (*definitions); ++ result = _asn1_expand_object_id (*definitions); + } + } + else +-- +1.8.3.1 + diff --git a/0003-_asn1_add_static_node-made-thread-safe.patch b/0003-_asn1_add_static_node-made-thread-safe.patch new file mode 100644 index 0000000000000000000000000000000000000000..a482fb03ca44bea3a80008fa215b1c231a2e485c --- /dev/null +++ b/0003-_asn1_add_static_node-made-thread-safe.patch @@ -0,0 +1,636 @@ +From 2f22074460817594a3fed3db46bb00b4ce11d00e Mon Sep 17 00:00:00 2001 +From: Nikos Mavrogiannopoulos +Date: Tue, 16 Jul 2019 14:27:56 +0200 +Subject: [PATCH] _asn1_add_static_node: made thread safe + +Signed-off-by: Nikos Mavrogiannopoulos +--- + lib/ASN1.y | 161 +++++++++++++++++++++++++++++-------------------------- + lib/parser_aux.c | 66 ++++++++++------------- + lib/parser_aux.h | 24 ++++++--- + lib/structure.c | 9 ++-- + 4 files changed, 135 insertions(+), 125 deletions(-) + +diff --git a/lib/ASN1.y b/lib/ASN1.y +index 1482fcd..cd783fe 100644 +--- a/lib/ASN1.y ++++ b/lib/ASN1.y +@@ -32,6 +32,7 @@ + #include + #include + ++static list_type *e_list = NULL; + static FILE *file_asn1; /* Pointer to file to parse */ + static int result_parse = 0; /* result of the parser + algorithm */ +@@ -144,7 +145,7 @@ static int _asn1_yylex(void); + definitions: definitions_id + DEFINITIONS explicit_implicit TAGS "::=" BEGIN /* imports_def */ + type_constant_list END +- {$$=_asn1_add_static_node(ASN1_ETYPE_DEFINITIONS|$3); ++ {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_DEFINITIONS|$3); + _asn1_set_name($$,_asn1_get_name($1)); + _asn1_set_name($1,""); + _asn1_set_right($1,$7); +@@ -178,9 +179,9 @@ pos_neg_identifier : pos_neg_num {snprintf($$,sizeof($$),"%s",$1);} + | IDENTIFIER {snprintf($$,sizeof($$),"%s",$1);} + ; + +-constant: '(' pos_neg_num ')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT); ++constant: '(' pos_neg_num ')' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_CONSTANT); + _asn1_set_value($$,$2,strlen($2)+1);} +- | IDENTIFIER'('pos_neg_num')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT); ++ | IDENTIFIER'('pos_neg_num')' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_CONSTANT); + _asn1_set_name($$,$1); + _asn1_set_value($$,$3,strlen($3)+1);} + ; +@@ -190,9 +191,9 @@ constant_list: constant {$$=$1;} + _asn1_set_right(_asn1_get_last_right($1),$3);} + ; + +-obj_constant: num_identifier {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT); ++obj_constant: num_identifier {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_CONSTANT); + _asn1_set_value($$,$1,strlen($1)+1);} +- | IDENTIFIER'('NUM')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT); ++ | IDENTIFIER'('NUM')' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_CONSTANT); + _asn1_set_name($$,$1); + _asn1_set_value($$,$3,strlen($3)+1);} + ; +@@ -207,9 +208,9 @@ class : UNIVERSAL {$$=CONST_UNIVERSAL;} + | APPLICATION {$$=CONST_APPLICATION;} + ; + +-tag_type : '[' NUM ']' {$$=_asn1_add_static_node(ASN1_ETYPE_TAG); ++tag_type : '[' NUM ']' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_TAG); + _asn1_set_value($$,$2,strlen($2)+1);} +- | '[' class NUM ']' {$$=_asn1_add_static_node(ASN1_ETYPE_TAG | $2); ++ | '[' class NUM ']' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_TAG | $2); + _asn1_set_value($$,$3,strlen($3)+1);} + ; + +@@ -218,10 +219,10 @@ tag : tag_type {$$=$1;} + | tag_type IMPLICIT {$$=_asn1_mod_type($1,CONST_IMPLICIT);} + ; + +-default : DEFAULT pos_neg_identifier {$$=_asn1_add_static_node(ASN1_ETYPE_DEFAULT); ++default : DEFAULT pos_neg_identifier {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_DEFAULT); + _asn1_set_value($$,$2,strlen($2)+1);} +- | DEFAULT ASN1_TRUE {$$=_asn1_add_static_node(ASN1_ETYPE_DEFAULT|CONST_TRUE);} +- | DEFAULT ASN1_FALSE {$$=_asn1_add_static_node(ASN1_ETYPE_DEFAULT|CONST_FALSE);} ++ | DEFAULT ASN1_TRUE {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_DEFAULT|CONST_TRUE);} ++ | DEFAULT ASN1_FALSE {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_DEFAULT|CONST_FALSE);} + ; + + +@@ -230,28 +231,28 @@ pos_neg_list: pos_neg_num + ; + + +-integer_def: INTEGER {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER);} +- | INTEGER'{'constant_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_LIST); ++integer_def: INTEGER {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_INTEGER);} ++ | INTEGER'{'constant_list'}' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_INTEGER|CONST_LIST); + _asn1_set_down($$,$3);} +- | integer_def'(' pos_neg_list ')' {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER);} ++ | integer_def'(' pos_neg_list ')' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_INTEGER);} + | integer_def'('int_identifier'.''.'int_identifier')' +- {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_MIN_MAX); +- _asn1_set_down($$,_asn1_add_static_node(ASN1_ETYPE_SIZE)); ++ {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_INTEGER|CONST_MIN_MAX); ++ _asn1_set_down($$,_asn1_add_static_node(&e_list, ASN1_ETYPE_SIZE)); + _asn1_set_value(_asn1_get_down($$),$6,strlen($6)+1); + _asn1_set_name(_asn1_get_down($$),$3);} + ; + +-boolean_def: BOOLEAN {$$=_asn1_add_static_node(ASN1_ETYPE_BOOLEAN);} ++boolean_def: BOOLEAN {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_BOOLEAN);} + ; + +-Time: UTCTime {$$=_asn1_add_static_node(ASN1_ETYPE_UTC_TIME);} +- | GeneralizedTime {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALIZED_TIME);} ++Time: UTCTime {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_UTC_TIME);} ++ | GeneralizedTime {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_GENERALIZED_TIME);} + ; + +-size_def2: SIZE'('num_identifier')' {$$=_asn1_add_static_node(ASN1_ETYPE_SIZE|CONST_1_PARAM); ++size_def2: SIZE'('num_identifier')' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_SIZE|CONST_1_PARAM); + _asn1_set_value($$,$3,strlen($3)+1);} + | SIZE'('num_identifier'.''.'num_identifier')' +- {$$=_asn1_add_static_node(ASN1_ETYPE_SIZE|CONST_MIN_MAX); ++ {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_SIZE|CONST_MIN_MAX); + _asn1_set_value($$,$3,strlen($3)+1); + _asn1_set_name($$,$6);} + ; +@@ -260,57 +261,57 @@ size_def: size_def2 {$$=$1;} + | '(' size_def2 ')' {$$=$2;} + ; + +-generalstring_def: GeneralString {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALSTRING);} +- | GeneralString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALSTRING|CONST_SIZE); ++generalstring_def: GeneralString {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_GENERALSTRING);} ++ | GeneralString size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_GENERALSTRING|CONST_SIZE); + _asn1_set_down($$,$2);} + ; + +-numericstring_def: NumericString {$$=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_UNIVERSAL);} +- | NumericString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_SIZE); ++numericstring_def: NumericString {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_NUMERIC_STRING|CONST_UNIVERSAL);} ++ | NumericString size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_NUMERIC_STRING|CONST_SIZE); + _asn1_set_down($$,$2);} + ; + +-ia5string_def: IA5String {$$=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING);} +- | IA5String size_def {$$=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING|CONST_SIZE); ++ia5string_def: IA5String {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_IA5_STRING);} ++ | IA5String size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_IA5_STRING|CONST_SIZE); + _asn1_set_down($$,$2);} + ; + +-teletexstring_def: TeletexString {$$=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING);} +- | TeletexString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING|CONST_SIZE); ++teletexstring_def: TeletexString {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_TELETEX_STRING);} ++ | TeletexString size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_TELETEX_STRING|CONST_SIZE); + _asn1_set_down($$,$2);} + ; + +-printablestring_def: PrintableString {$$=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING);} +- | PrintableString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING|CONST_SIZE); ++printablestring_def: PrintableString {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_PRINTABLE_STRING);} ++ | PrintableString size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_PRINTABLE_STRING|CONST_SIZE); + _asn1_set_down($$,$2);} + ; + +-universalstring_def: UniversalString {$$=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING);} +- | UniversalString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING|CONST_SIZE); ++universalstring_def: UniversalString {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_UNIVERSAL_STRING);} ++ | UniversalString size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_UNIVERSAL_STRING|CONST_SIZE); + _asn1_set_down($$,$2);} + ; + +-bmpstring_def: BMPString {$$=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING);} +- | BMPString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING|CONST_SIZE); ++bmpstring_def: BMPString {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_BMP_STRING);} ++ | BMPString size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_BMP_STRING|CONST_SIZE); + _asn1_set_down($$,$2);} + ; + +-utf8string_def: UTF8String {$$=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING);} +- | UTF8String size_def {$$=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING|CONST_SIZE); ++utf8string_def: UTF8String {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_UTF8_STRING);} ++ | UTF8String size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_UTF8_STRING|CONST_SIZE); + _asn1_set_down($$,$2);} + ; + +-visiblestring_def: VisibleString {$$=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING);} +- | VisibleString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING|CONST_SIZE); ++visiblestring_def: VisibleString {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_VISIBLE_STRING);} ++ | VisibleString size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_VISIBLE_STRING|CONST_SIZE); + _asn1_set_down($$,$2);} + ; + +-octet_string_def : OCTET STRING {$$=_asn1_add_static_node(ASN1_ETYPE_OCTET_STRING);} +- | OCTET STRING size_def {$$=_asn1_add_static_node(ASN1_ETYPE_OCTET_STRING|CONST_SIZE); ++octet_string_def : OCTET STRING {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_OCTET_STRING);} ++ | OCTET STRING size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_OCTET_STRING|CONST_SIZE); + _asn1_set_down($$,$3);} + ; + +-bit_element : IDENTIFIER'('NUM')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT); ++bit_element : IDENTIFIER'('NUM')' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_CONSTANT); + _asn1_set_name($$,$1); + _asn1_set_value($$,$3,strlen($3)+1);} + ; +@@ -320,25 +321,25 @@ bit_element_list : bit_element {$$=$1;} + _asn1_set_right(_asn1_get_last_right($1),$3);} + ; + +-bit_string_def : BIT STRING {$$=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING);} +- | BIT STRING size_def {$$=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING|CONST_SIZE);} ++bit_string_def : BIT STRING {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_BIT_STRING);} ++ | BIT STRING size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_BIT_STRING|CONST_SIZE);} + | BIT STRING'{'bit_element_list'}' +- {$$=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING|CONST_LIST); ++ {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_BIT_STRING|CONST_LIST); + _asn1_set_down($$,$4);} + ; + + enumerated_def : ENUMERATED'{'bit_element_list'}' +- {$$=_asn1_add_static_node(ASN1_ETYPE_ENUMERATED|CONST_LIST); ++ {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_ENUMERATED|CONST_LIST); + _asn1_set_down($$,$3);} + ; + + +-object_def : OBJECT STR_IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);} ++object_def : OBJECT STR_IDENTIFIER {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_OBJECT_ID);} + ; + +-type_assig_right: IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER); ++type_assig_right: IDENTIFIER {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_IDENTIFIER); + _asn1_set_value($$,$1,strlen($1)+1);} +- | IDENTIFIER size_def {$$=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER|CONST_SIZE); ++ | IDENTIFIER size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_IDENTIFIER|CONST_SIZE); + _asn1_set_value($$,$1,strlen($1)+1); + _asn1_set_down($$,$2);} + | integer_def {$$=$1;} +@@ -361,7 +362,7 @@ type_assig_right: IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_IDENT + | choise_def {$$=$1;} + | any_def {$$=$1;} + | set_def {$$=$1;} +- | TOKEN_NULL {$$=_asn1_add_static_node(ASN1_ETYPE_NULL);} ++ | TOKEN_NULL {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_NULL);} + ; + + type_assig_right_tag : type_assig_right {$$=$1;} +@@ -385,31 +386,31 @@ type_assig_list : type_assig {$$=$1;} + _asn1_set_right(_asn1_get_last_right($1),$3);} + ; + +-sequence_def : SEQUENCE'{'type_assig_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE); ++sequence_def : SEQUENCE'{'type_assig_list'}' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_SEQUENCE); + _asn1_set_down($$,$3);} +- | SEQUENCE OF type_assig_right {$$=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE_OF); ++ | SEQUENCE OF type_assig_right {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_SEQUENCE_OF); + _asn1_set_down($$,$3);} +- | SEQUENCE size_def OF type_assig_right {$$=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE_OF|CONST_SIZE); ++ | SEQUENCE size_def OF type_assig_right {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_SEQUENCE_OF|CONST_SIZE); + _asn1_set_right($2,$4); + _asn1_set_down($$,$2);} + ; + +-set_def : SET'{'type_assig_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_SET); ++set_def : SET'{'type_assig_list'}' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_SET); + _asn1_set_down($$,$3);} +- | SET OF type_assig_right {$$=_asn1_add_static_node(ASN1_ETYPE_SET_OF); ++ | SET OF type_assig_right {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_SET_OF); + _asn1_set_down($$,$3);} +- | SET size_def OF type_assig_right {$$=_asn1_add_static_node(ASN1_ETYPE_SET_OF|CONST_SIZE); ++ | SET size_def OF type_assig_right {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_SET_OF|CONST_SIZE); + _asn1_set_right($2,$4); + _asn1_set_down($$,$2);} + ; + +-choise_def : CHOICE'{'type_assig_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_CHOICE); ++choise_def : CHOICE'{'type_assig_list'}' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_CHOICE); + _asn1_set_down($$,$3);} + ; + +-any_def : ANY {$$=_asn1_add_static_node(ASN1_ETYPE_ANY);} +- | ANY DEFINED BY IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_ANY|CONST_DEFINED_BY); +- _asn1_set_down($$,_asn1_add_static_node(ASN1_ETYPE_CONSTANT)); ++any_def : ANY {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_ANY);} ++ | ANY DEFINED BY IDENTIFIER {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_ANY|CONST_DEFINED_BY); ++ _asn1_set_down($$,_asn1_add_static_node(&e_list, ASN1_ETYPE_CONSTANT)); + _asn1_set_name(_asn1_get_down($$),$4);} + ; + +@@ -419,16 +420,16 @@ type_def : IDENTIFIER "::=" type_assig_right_tag {$$=_asn1_set_name($3,$1);} + ; + + constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}' +- {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN); ++ {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN); + _asn1_set_name($$,$1); + _asn1_set_down($$,$6);} + | IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}' +- {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM); ++ {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM); + _asn1_set_name($$,$1); + _asn1_set_value($$,$2,strlen($2)+1); + _asn1_set_down($$,$5);} + | IDENTIFIER INTEGER "::=" pos_neg_num +- {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_ASSIGN); ++ {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_INTEGER|CONST_ASSIGN); + _asn1_set_name($$,$1); + _asn1_set_value($$,$4,strlen($4)+1);} + ; +@@ -442,29 +443,29 @@ type_constant_list : type_constant {$$=$1;} + _asn1_set_right(_asn1_get_last_right($1),$2);} + ; + +-definitions_id : IDENTIFIER '{' obj_constant_list '}' {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID); ++definitions_id : IDENTIFIER '{' obj_constant_list '}' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_OBJECT_ID); + _asn1_set_down($$,$3); + _asn1_set_name($$,$1);} +- | IDENTIFIER '{' '}' {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID); ++ | IDENTIFIER '{' '}' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_OBJECT_ID); + _asn1_set_name($$,$1);} +- | IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID); ++ | IDENTIFIER {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_OBJECT_ID); + _asn1_set_name($$,$1);} + ; + + /* +-identifier_list : IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER); ++identifier_list : IDENTIFIER {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_IDENTIFIER); + _asn1_set_name($$,$1);} + | identifier_list IDENTIFIER + {$$=$1; +- _asn1_set_right(_asn1_get_last_right($$),_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER)); ++ _asn1_set_right(_asn1_get_last_right($$),_asn1_add_static_node(&e_list, ASN1_ETYPE_IDENTIFIER)); + _asn1_set_name(_asn1_get_last_right($$),$2);} + ; + + + imports_def : empty {$$=NULL;} + | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list +- {$$=_asn1_add_static_node(ASN1_ETYPE_IMPORTS); +- _asn1_set_down($$,_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID)); ++ {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_IMPORTS); ++ _asn1_set_down($$,_asn1_add_static_node(&e_list, ASN1_ETYPE_OBJECT_ID)); + _asn1_set_name(_asn1_get_down($$),$4); + _asn1_set_down(_asn1_get_down($$),$5); + _asn1_set_right($$,$2);} +@@ -706,23 +707,30 @@ asn1_parser2tree (const char *file, asn1_node * definitions, + if (result_parse == ASN1_SUCCESS) + { /* all identifier defined */ + /* Delete the list and keep the ASN1 structure */ +- _asn1_delete_list (); ++ _asn1_delete_list (e_list); ++ e_list = NULL; + /* Convert into DER coding the value assign to INTEGER constants */ + _asn1_change_integer_value (p_tree); + /* Expand the IDs of OBJECT IDENTIFIER constants */ +- result_parse = _asn1_expand_object_id (p_tree); ++ result_parse = _asn1_expand_object_id (e_list, p_tree); + if (result_parse != ASN1_SUCCESS) + goto error; + + *definitions = p_tree; + } + else /* some identifiers not defined */ +- /* Delete the list and the ASN1 structure */ +- _asn1_delete_list_and_nodes (); ++ { ++ /* Delete the list and the ASN1 structure */ ++ _asn1_delete_list_and_nodes (e_list); ++ e_list = NULL; ++ } + } + else /* syntax error */ +- /* Delete the list and the ASN1 structure */ +- _asn1_delete_list_and_nodes (); ++ { ++ /* Delete the list and the ASN1 structure */ ++ _asn1_delete_list_and_nodes (e_list); ++ e_list = NULL; ++ } + } + + error: +@@ -864,7 +872,8 @@ asn1_parser2array (const char *inputFileName, const char *outputFileName, + } /* result == OK */ + + /* Delete the list and the ASN1 structure */ +- _asn1_delete_list_and_nodes (); ++ _asn1_delete_list_and_nodes (e_list); ++ e_list = NULL; + } /* inputFile exist */ + + _asn1_create_errorDescription (result_parse, error_desc); +diff --git a/lib/parser_aux.c b/lib/parser_aux.c +index 7d96bea..b182948 100644 +--- a/lib/parser_aux.c ++++ b/lib/parser_aux.c +@@ -28,50 +28,37 @@ + + char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */ + +-/***********************************************/ +-/* Type: list_type */ +-/* Description: type used in the list during */ +-/* the structure creation. */ +-/***********************************************/ +-typedef struct list_struct +-{ +- asn1_node node; +- struct list_struct *next; +-} list_type; +- +- +-/* Pointer to the first element of the list */ +-list_type *firstElement = NULL; + + /******************************************************/ + /* Function : _asn1_add_static_node */ + /* Description: creates a new NODE_ASN element and */ +-/* puts it in the list pointed by firstElement. */ ++/* puts it in the list pointed by e_list. */ + /* Parameters: */ ++/* e_list: of type list_type; must be NULL initially */ + /* type: type of the new element (see ASN1_ETYPE_ */ + /* and CONST_ constants). */ + /* Return: pointer to the new element. */ + /******************************************************/ + asn1_node +-_asn1_add_static_node (unsigned int type) ++_asn1_add_static_node (list_type **e_list, unsigned int type) + { +- list_type *listElement; ++ list_type *p; + asn1_node punt; + + punt = calloc (1, sizeof (struct asn1_node_st)); + if (punt == NULL) + return NULL; + +- listElement = malloc (sizeof (list_type)); +- if (listElement == NULL) ++ p = malloc (sizeof (list_type)); ++ if (p == NULL) + { + free (punt); + return NULL; + } + +- listElement->node = punt; +- listElement->next = firstElement; +- firstElement = listElement; ++ p->node = punt; ++ p->next = *e_list; ++ *e_list = p; + + punt->type = type; + +@@ -521,9 +508,9 @@ _asn1_find_up (asn1_node_const node) + /* Description: deletes the list element given */ + /******************************************************************/ + static void +-_asn1_delete_node_from_list (asn1_node node) ++_asn1_delete_node_from_list (list_type *list, asn1_node node) + { +- list_type *p = firstElement; ++ list_type *p = list; + + while (p) + { +@@ -539,15 +526,15 @@ _asn1_delete_node_from_list (asn1_node node) + /* pointed by them). */ + /******************************************************************/ + void +-_asn1_delete_list (void) ++_asn1_delete_list (list_type *e_list) + { +- list_type *listElement; ++ list_type *p; + +- while (firstElement) ++ while (e_list) + { +- listElement = firstElement; +- firstElement = firstElement->next; +- free (listElement); ++ p = e_list; ++ e_list = e_list->next; ++ free (p); + } + } + +@@ -557,16 +544,16 @@ _asn1_delete_list (void) + /* pointed by them. */ + /******************************************************************/ + void +-_asn1_delete_list_and_nodes (void) ++_asn1_delete_list_and_nodes (list_type *e_list) + { +- list_type *listElement; ++ list_type *p; + +- while (firstElement) ++ while (e_list) + { +- listElement = firstElement; +- firstElement = firstElement->next; +- _asn1_remove_node (listElement->node, 0); +- free (listElement); ++ p = e_list; ++ e_list = e_list->next; ++ _asn1_remove_node (p->node, 0); ++ free (p); + } + } + +@@ -682,13 +669,14 @@ _asn1_change_integer_value (asn1_node node) + /* Function : _asn1_expand_object_id */ + /* Description: expand the IDs of an OBJECT IDENTIFIER constant. */ + /* Parameters: */ ++/* list: root of an object list */ + /* node: root of an ASN1 element. */ + /* Return: */ + /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ + /* otherwise ASN1_SUCCESS */ + /******************************************************************/ + int +-_asn1_expand_object_id (asn1_node node) ++_asn1_expand_object_id (list_type *list, asn1_node node) + { + asn1_node p, p2, p3, p4, p5; + char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1]; +@@ -725,7 +713,7 @@ _asn1_expand_object_id (asn1_node node) + || !(p3->type & CONST_ASSIGN)) + return ASN1_ELEMENT_NOT_FOUND; + _asn1_set_down (p, p2->right); +- _asn1_delete_node_from_list(p2); ++ _asn1_delete_node_from_list(list, p2); + _asn1_remove_node (p2, 0); + p2 = p; + p4 = p3->down; +diff --git a/lib/parser_aux.h b/lib/parser_aux.h +index 42e9071..c21d20d 100644 +--- a/lib/parser_aux.h ++++ b/lib/parser_aux.h +@@ -22,10 +22,26 @@ + #ifndef _PARSER_AUX_H + #define _PARSER_AUX_H + ++/***********************************************/ ++/* Type: list_type */ ++/* Description: type used in the list during */ ++/* the structure creation. */ ++/***********************************************/ ++typedef struct list_struct ++{ ++ asn1_node node; ++ struct list_struct *next; ++} list_type; ++ + /***************************************/ + /* Functions used by ASN.1 parser */ + /***************************************/ +-asn1_node _asn1_add_static_node (unsigned int type); ++asn1_node _asn1_add_static_node (list_type **e_list, unsigned int type); ++ ++void _asn1_delete_list (list_type *e_list); ++ ++void _asn1_delete_list_and_nodes (list_type *e_list); ++ + + asn1_node + _asn1_set_value (asn1_node node, const void *value, unsigned int len); +@@ -48,10 +64,6 @@ asn1_node _asn1_get_last_right (asn1_node_const node); + + void _asn1_remove_node (asn1_node node, unsigned int flags); + +-void _asn1_delete_list (void); +- +-void _asn1_delete_list_and_nodes (void); +- + /* Max 64-bit integer length is 20 chars + 1 for sign + 1 for null termination */ + #define LTOSTR_MAX_SIZE 22 + char *_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]); +@@ -61,7 +73,7 @@ asn1_node _asn1_find_up (asn1_node_const node); + int _asn1_change_integer_value (asn1_node node); + + #define EXPAND_OBJECT_ID_MAX_RECURSION 16 +-int _asn1_expand_object_id (asn1_node node); ++int _asn1_expand_object_id (list_type *list, asn1_node node); + + int _asn1_type_set_config (asn1_node node); + +diff --git a/lib/structure.c b/lib/structure.c +index 4b0ea2f..98393cc 100644 +--- a/lib/structure.c ++++ b/lib/structure.c +@@ -182,6 +182,7 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + int move; + int result; + unsigned int type; ++ list_type *e_list = NULL; + + if (errorDescription) + errorDescription[0] = 0; +@@ -196,7 +197,7 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + { + type = convert_old_type (array[k].type); + +- p = _asn1_add_static_node (type & (~CONST_DOWN)); ++ p = _asn1_add_static_node (&e_list, type & (~CONST_DOWN)); + if (array[k].name) + _asn1_set_name (p, array[k].name); + if (array[k].value) +@@ -245,7 +246,7 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + if (result == ASN1_SUCCESS) + { + _asn1_change_integer_value (*definitions); +- result = _asn1_expand_object_id (*definitions); ++ result = _asn1_expand_object_id (e_list, *definitions); + } + } + else +@@ -267,11 +268,11 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + + if (result != ASN1_SUCCESS) + { +- _asn1_delete_list_and_nodes (); ++ _asn1_delete_list_and_nodes (e_list); + *definitions = NULL; + } + else +- _asn1_delete_list (); ++ _asn1_delete_list (e_list); + + return result; + } +-- +1.8.3.1 + diff --git a/0004-_asn1_expand_object_id-fix-memory-leak-on-error.patch b/0004-_asn1_expand_object_id-fix-memory-leak-on-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..7330fe6ae2eb8b1e27fb0e2be927a1ebf997c679 --- /dev/null +++ b/0004-_asn1_expand_object_id-fix-memory-leak-on-error.patch @@ -0,0 +1,111 @@ +From b50d5e532c53cbd7a48dd0864aeb9676486f67d0 Mon Sep 17 00:00:00 2001 +From: Nikos Mavrogiannopoulos +Date: Fri, 19 Jul 2019 20:39:10 +0200 +Subject: [PATCH] _asn1_expand_object_id: fix memory leak on error + +Signed-off-by: Nikos Mavrogiannopoulos +--- + lib/ASN1.y | 2 +- + lib/parser_aux.c | 24 ++++++++++++++++++++++-- + lib/parser_aux.h | 2 +- + lib/structure.c | 2 +- + 4 files changed, 25 insertions(+), 5 deletions(-) + +diff --git a/lib/ASN1.y b/lib/ASN1.y +index 97f5a5c..5009173 100644 +--- a/lib/ASN1.y ++++ b/lib/ASN1.y +@@ -703,7 +703,7 @@ asn1_parser2tree (const char *file, asn1_node * definitions, + /* Convert into DER coding the value assign to INTEGER constants */ + _asn1_change_integer_value (p_tree); + /* Expand the IDs of OBJECT IDENTIFIER constants */ +- result_parse = _asn1_expand_object_id (e_list, p_tree); ++ result_parse = _asn1_expand_object_id (&e_list, p_tree); + if (result_parse != ASN1_SUCCESS) + goto error; + +diff --git a/lib/parser_aux.c b/lib/parser_aux.c +index 4232dc1..305cf16 100644 +--- a/lib/parser_aux.c ++++ b/lib/parser_aux.c +@@ -65,6 +65,24 @@ _asn1_add_static_node (list_type **e_list, unsigned int type) + return punt; + } + ++static ++int _asn1_add_static_node2 (list_type **e_list, asn1_node node) ++{ ++ list_type *p; ++ ++ p = malloc (sizeof (list_type)); ++ if (p == NULL) ++ { ++ return -1; ++ } ++ ++ p->node = node; ++ p->next = *e_list; ++ *e_list = p; ++ ++ return 0; ++} ++ + /** + * asn1_find_node: + * @pointer: NODE_ASN element pointer. +@@ -676,7 +694,7 @@ _asn1_change_integer_value (asn1_node node) + /* otherwise ASN1_SUCCESS */ + /******************************************************************/ + int +-_asn1_expand_object_id (list_type *list, asn1_node node) ++_asn1_expand_object_id (list_type **list, asn1_node node) + { + asn1_node p, p2, p3, p4, p5; + char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1]; +@@ -713,7 +731,7 @@ _asn1_expand_object_id (list_type *list, asn1_node node) + || !(p3->type & CONST_ASSIGN)) + return ASN1_ELEMENT_NOT_FOUND; + _asn1_set_down (p, p2->right); +- _asn1_delete_node_from_list(list, p2); ++ _asn1_delete_node_from_list(*list, p2); + _asn1_remove_node (p2, 0); + p2 = p; + p4 = p3->down; +@@ -730,6 +748,8 @@ _asn1_expand_object_id (list_type *list, asn1_node node) + if (tlen > 0) + _asn1_set_value (p5, p4->value, tlen + 1); + } ++ _asn1_add_static_node2(list, p5); ++ + if (p2 == p) + { + _asn1_set_right (p5, p->down); +diff --git a/lib/parser_aux.h b/lib/parser_aux.h +index 5fbdbc0..8dda857 100644 +--- a/lib/parser_aux.h ++++ b/lib/parser_aux.h +@@ -73,7 +73,7 @@ asn1_node _asn1_find_up (asn1_node node); + int _asn1_change_integer_value (asn1_node node); + + #define EXPAND_OBJECT_ID_MAX_RECURSION 16 +-int _asn1_expand_object_id (list_type *list, asn1_node node); ++int _asn1_expand_object_id (list_type **list, asn1_node node); + + int _asn1_type_set_config (asn1_node node); + +diff --git a/lib/structure.c b/lib/structure.c +index 9d8684c..4e371f3 100644 +--- a/lib/structure.c ++++ b/lib/structure.c +@@ -246,7 +246,7 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + if (result == ASN1_SUCCESS) + { + _asn1_change_integer_value (*definitions); +- result = _asn1_expand_object_id (e_list, *definitions); ++ result = _asn1_expand_object_id (&e_list, *definitions); + } + } + else +-- +1.8.3.1 + diff --git a/0005-Fix-two-memleaks-in-asn1_array2tree.patch b/0005-Fix-two-memleaks-in-asn1_array2tree.patch new file mode 100644 index 0000000000000000000000000000000000000000..4e40c60cfcb7a8fd11d1c4fe2e2d69231c002397 --- /dev/null +++ b/0005-Fix-two-memleaks-in-asn1_array2tree.patch @@ -0,0 +1,100 @@ +From f16d1ff9a283276d105b50391d30f4b9039d5f80 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tim=20R=C3=BChsen?= +Date: Tue, 23 Jul 2019 12:04:56 +0200 +Subject: [PATCH] Fix two memleaks in asn1_array2tree() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Tim Rühsen +--- + lib/parser_aux.c | 2 +- + lib/parser_aux.h | 1 + + lib/structure.c | 22 +++++++++++++--------- + 3 files changed, 15 insertions(+), 10 deletions(-) + +diff --git a/lib/parser_aux.c b/lib/parser_aux.c +index 9df1152..fec4175 100644 +--- a/lib/parser_aux.c ++++ b/lib/parser_aux.c +@@ -548,7 +548,7 @@ _asn1_find_up (asn1_node_const node) + /* Function : _asn1_delete_node_from_list */ + /* Description: deletes the list element given */ + /******************************************************************/ +-static void ++void + _asn1_delete_node_from_list (list_type *list, asn1_node node) + { + list_type *p = list; +diff --git a/lib/parser_aux.h b/lib/parser_aux.h +index 019f55e..598e684 100644 +--- a/lib/parser_aux.h ++++ b/lib/parser_aux.h +@@ -42,6 +42,7 @@ void _asn1_delete_list (list_type *e_list); + + void _asn1_delete_list_and_nodes (list_type *e_list); + ++void _asn1_delete_node_from_list (list_type *list, asn1_node node); + + asn1_node + _asn1_set_value (asn1_node node, const void *value, unsigned int len); +diff --git a/lib/structure.c b/lib/structure.c +index 590439c..1de5226 100644 +--- a/lib/structure.c ++++ b/lib/structure.c +@@ -192,8 +192,7 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + + move = UP; + +- k = 0; +- while (array[k].value || array[k].type || array[k].name) ++ for (k = 0; array[k].value || array[k].type || array[k].name; k++) + { + type = convert_old_type (array[k].type); + +@@ -206,10 +205,19 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + if (*definitions == NULL) + *definitions = p; + +- if (move == DOWN) ++ if (move == DOWN) { ++ if (p_last && p_last->down) { ++ _asn1_delete_node_from_list (e_list, p_last->down); ++ _asn1_remove_node (p_last->down, 0); ++ } + _asn1_set_down (p_last, p); +- else if (move == RIGHT) ++ } else if (move == RIGHT) { ++ if (p_last && p_last->right) { ++ _asn1_delete_node_from_list (e_list, p_last->right); ++ _asn1_remove_node (p_last->down, 0); ++ } + _asn1_set_right (p_last, p); ++ } + + p_last = p; + +@@ -219,11 +227,8 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + move = RIGHT; + else + { +- while (1) ++ while (p_last != *definitions) + { +- if (p_last == *definitions) +- break; +- + p_last = _asn1_find_up (p_last); + + if (p_last == NULL) +@@ -237,7 +242,6 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + } + } /* while */ + } +- k++; + } /* while */ + + if (p_last == *definitions) +-- +1.8.3.1 + diff --git a/0006-Fix-memleaks-in-asn1_array2tree.patch b/0006-Fix-memleaks-in-asn1_array2tree.patch new file mode 100644 index 0000000000000000000000000000000000000000..8374feb1099a375b9b0facd0ac289ff29c79df7e --- /dev/null +++ b/0006-Fix-memleaks-in-asn1_array2tree.patch @@ -0,0 +1,145 @@ +From b8c28cbb46fbcf7fe46f456b6c375c7535b08c19 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tim=20R=C3=BChsen?= +Date: Tue, 30 Jul 2019 12:07:12 +0200 +Subject: [PATCH] Fix memleaks in asn1_array2tree() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce _asn1_delete_structure() that keeps the node list +in sync when deleting a tree structure. + +Signed-off-by: Tim Rühsen +--- + lib/parser_aux.c | 6 +++--- + lib/structure.c | 25 +++++++++++++++---------- + lib/structure.h | 5 +++++ + 3 files changed, 23 insertions(+), 13 deletions(-) + +diff --git a/lib/parser_aux.c b/lib/parser_aux.c +index 37afa5d..0fead92 100644 +--- a/lib/parser_aux.c ++++ b/lib/parser_aux.c +@@ -723,14 +723,15 @@ _asn1_expand_object_id (list_type **list, asn1_node node) + { + _asn1_str_cpy (name2, sizeof (name2), name_root); + _asn1_str_cat (name2, sizeof (name2), "."); +- _asn1_str_cat (name2, sizeof (name2), +- (char *) p2->value); ++ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); + p3 = asn1_find_node (node, name2); + if (!p3 + || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) + || !(p3->type & CONST_ASSIGN)) + return ASN1_ELEMENT_NOT_FOUND; + _asn1_set_down (p, p2->right); ++ if (p2->down) ++ _asn1_delete_structure (*list, &p2->down, 0); + _asn1_delete_node_from_list(*list, p2); + _asn1_remove_node (p2, 0); + p2 = p; +@@ -805,7 +806,6 @@ _asn1_expand_object_id (list_type **list, asn1_node node) + p = _asn1_find_up (p); + } + +- + /*******************************/ + /* expand DEFAULT */ + /*******************************/ +diff --git a/lib/structure.c b/lib/structure.c +index 8d71970..7f52380 100644 +--- a/lib/structure.c ++++ b/lib/structure.c +@@ -206,16 +206,12 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + *definitions = p; + + if (move == DOWN) { +- if (p_last && p_last->down) { +- _asn1_delete_node_from_list (e_list, p_last->down); +- _asn1_remove_node (p_last->down, 0); +- } ++ if (p_last && p_last->down) ++ _asn1_delete_structure (e_list, &p_last->down, 0); + _asn1_set_down (p_last, p); + } else if (move == RIGHT) { +- if (p_last && p_last->right) { +- _asn1_delete_node_from_list (e_list, p_last->right); +- _asn1_remove_node (p_last->down, 0); +- } ++ if (p_last && p_last->right) ++ _asn1_delete_structure (e_list, &p_last->right, 0); + _asn1_set_right (p_last, p); + } + +@@ -294,7 +290,7 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + int + asn1_delete_structure (asn1_node * structure) + { +- return asn1_delete_structure2(structure, 0); ++ return _asn1_delete_structure (NULL, structure, 0); + } + + /** +@@ -311,6 +307,12 @@ asn1_delete_structure (asn1_node * structure) + int + asn1_delete_structure2 (asn1_node * structure, unsigned int flags) + { ++ return _asn1_delete_structure (NULL, structure, flags); ++} ++ ++int ++_asn1_delete_structure (list_type *e_list, asn1_node * structure, unsigned int flags) ++{ + asn1_node p, p2, p3; + + if (*structure == NULL) +@@ -330,6 +332,8 @@ asn1_delete_structure2 (asn1_node * structure, unsigned int flags) + { + p3 = _asn1_find_up (p); + _asn1_set_down (p3, p2); ++ if (e_list) ++ _asn1_delete_node_from_list (e_list, p); + _asn1_remove_node (p, flags); + p = p3; + } +@@ -349,6 +353,8 @@ asn1_delete_structure2 (asn1_node * structure, unsigned int flags) + } + else + _asn1_set_right (p3, p2); ++ if (e_list) ++ _asn1_delete_node_from_list (e_list, p); + _asn1_remove_node (p, flags); + p = NULL; + } +@@ -360,7 +366,6 @@ asn1_delete_structure2 (asn1_node * structure, unsigned int flags) + } + + +- + /** + * asn1_delete_element: + * @structure: pointer to the structure that contains the element you +diff --git a/lib/structure.h b/lib/structure.h +index bb6e7a9..075e2f9 100644 +--- a/lib/structure.h ++++ b/lib/structure.h +@@ -28,6 +28,8 @@ + #ifndef _STRUCTURE_H + #define _STRUCTURE_H + ++#include "parser_aux.h" // list_type ++ + int _asn1_create_static_structure (asn1_node pointer, + char *output_file_name, char *vector_name); + +@@ -37,4 +39,7 @@ asn1_node _asn1_add_single_node (unsigned int type); + + asn1_node _asn1_find_left (asn1_node node); + ++int ++_asn1_delete_structure (list_type *e_list, asn1_node *structure, unsigned int flags); ++ + #endif +-- +1.8.3.1 + diff --git a/0007-fix-memleaks-in-asn1-arrat2tree.patch b/0007-fix-memleaks-in-asn1-arrat2tree.patch new file mode 100644 index 0000000000000000000000000000000000000000..983c6159ddef57605b4e4ee4405d7f22f413b549 --- /dev/null +++ b/0007-fix-memleaks-in-asn1-arrat2tree.patch @@ -0,0 +1,201 @@ +From ea0e4fc2567edfc0d20141025837e2bd9c64c0cb Mon Sep 17 00:00:00 2001 +From: opneErler BUildteam +Date: Fri, 5 Jun 2020 15:46:37 +0800 +Subject: [PATCH] fix memleaks in asn1 arrat2tree + +--- + lib/ASN1.y | 91 ++++++++++++++++++++++++-------------------------------- + lib/parser_aux.c | 2 +- + lib/structure.c | 20 +++++++++---- + 3 files changed, 54 insertions(+), 59 deletions(-) + +diff --git a/lib/ASN1.y b/lib/ASN1.y +index 5009173..b540457 100644 +--- a/lib/ASN1.y ++++ b/lib/ASN1.y +@@ -661,13 +661,11 @@ int + asn1_parser2tree (const char *file, asn1_node * definitions, + char *error_desc) + { +- +- p_tree = NULL; +- + if (*definitions != NULL) +- return ASN1_ELEMENT_NOT_EMPTY; +- +- *definitions = NULL; ++ { ++ result_parse = ASN1_ELEMENT_NOT_EMPTY; ++ goto error; ++ } + + file_name = file; + +@@ -677,54 +675,43 @@ asn1_parser2tree (const char *file, asn1_node * definitions, + if (file_asn1 == NULL) + { + result_parse = ASN1_FILE_NOT_FOUND; ++ goto error; + } +- else +- { +- result_parse = ASN1_SUCCESS; +- +- line_number = 1; +- yyparse (); +- +- fclose (file_asn1); +- +- if (result_parse == ASN1_SUCCESS) +- { /* syntax OK */ +- /* set IMPLICIT or EXPLICIT property */ +- _asn1_set_default_tag (p_tree); +- /* set CONST_SET and CONST_NOT_USED */ +- _asn1_type_set_config (p_tree); +- /* check the identifier definitions */ +- result_parse = _asn1_check_identifier (p_tree); +- if (result_parse == ASN1_SUCCESS) +- { /* all identifier defined */ +- /* Delete the list and keep the ASN1 structure */ +- _asn1_delete_list (e_list); +- e_list = NULL; +- /* Convert into DER coding the value assign to INTEGER constants */ +- _asn1_change_integer_value (p_tree); +- /* Expand the IDs of OBJECT IDENTIFIER constants */ +- result_parse = _asn1_expand_object_id (&e_list, p_tree); +- if (result_parse != ASN1_SUCCESS) +- goto error; +- +- *definitions = p_tree; +- } +- else /* some identifiers not defined */ +- { +- /* Delete the list and the ASN1 structure */ +- _asn1_delete_list_and_nodes (e_list); +- e_list = NULL; +- } +- } +- else /* syntax error */ +- { +- /* Delete the list and the ASN1 structure */ +- _asn1_delete_list_and_nodes (e_list); +- e_list = NULL; +- } +- } ++ result_parse = ASN1_SUCCESS; ++ line_number = 1; ++ yyparse (); ++ ++ fclose (file_asn1); ++ ++ if (result_parse != ASN1_SUCCESS) ++ goto error; ++ ++ /* set IMPLICIT or EXPLICIT property */ ++ _asn1_set_default_tag (p_tree); ++ /* set CONST_SET and CONST_NOT_USED */ ++ _asn1_type_set_config (p_tree); ++ /* check the identifier definitions */ ++ result_parse = _asn1_check_identifier (p_tree); ++ if (result_parse != ASN1_SUCCESS) ++ goto error; ++ /* Convert into DER coding the value assign to INTEGER constants */ ++ _asn1_change_integer_value (p_tree); ++ /* Expand the IDs of OBJECT IDENTIFIER constants */ ++ result_parse = _asn1_expand_object_id (&e_list, p_tree); ++ if (result_parse != ASN1_SUCCESS) ++ goto error; ++/* success */ ++ *definitions = p_tree; ++ _asn1_delete_list (e_list); ++ e_list = NULL; ++ p_tree = NULL; ++ *error_desc = 0; ++ return result_parse; ++error: ++ _asn1_delete_list_and_nodes (e_list); ++ e_list = NULL; ++ p_tree = NULL; + +- error: + _asn1_create_errorDescription (result_parse, error_desc); + + return result_parse; +diff --git a/lib/parser_aux.c b/lib/parser_aux.c +index 0fead92..5b3e55b 100644 +--- a/lib/parser_aux.c ++++ b/lib/parser_aux.c +@@ -730,7 +730,7 @@ _asn1_expand_object_id (list_type **list, asn1_node node) + || !(p3->type & CONST_ASSIGN)) + return ASN1_ELEMENT_NOT_FOUND; + _asn1_set_down (p, p2->right); +- if (p2->down) ++ while (p2->down) + _asn1_delete_structure (*list, &p2->down, 0); + _asn1_delete_node_from_list(*list, p2); + _asn1_remove_node (p2, 0); +diff --git a/lib/structure.c b/lib/structure.c +index 7f52380..642816a 100644 +--- a/lib/structure.c ++++ b/lib/structure.c +@@ -206,11 +206,11 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, + *definitions = p; + + if (move == DOWN) { +- if (p_last && p_last->down) ++ while (p_last && p_last->down) + _asn1_delete_structure (e_list, &p_last->down, 0); + _asn1_set_down (p_last, p); + } else if (move == RIGHT) { +- if (p_last && p_last->right) ++ while (p_last && p_last->right) + _asn1_delete_structure (e_list, &p_last->right, 0); + _asn1_set_right (p_last, p); + } +@@ -314,7 +314,7 @@ int + _asn1_delete_structure (list_type *e_list, asn1_node * structure, unsigned int flags) + { + asn1_node p, p2, p3; +- ++ int flag_t = 1; + if (*structure == NULL) + return ASN1_ELEMENT_NOT_FOUND; + +@@ -344,7 +344,11 @@ _asn1_delete_structure (list_type *e_list, asn1_node * structure, unsigned int f + { + p3 = _asn1_find_up (p); + if (p3) ++ { + _asn1_set_down (p3, p2); ++ p2 = NULL; ++ flag_t = 0; ++ } + else + { + if (p->right) +@@ -352,15 +356,19 @@ _asn1_delete_structure (list_type *e_list, asn1_node * structure, unsigned int f + } + } + else +- _asn1_set_right (p3, p2); ++ { ++ _asn1_set_right (p3, p2); ++ p2 = NULL; ++ flag_t = 0; ++ } + if (e_list) + _asn1_delete_node_from_list (e_list, p); + _asn1_remove_node (p, flags); +- p = NULL; ++ p = p2; + } + } + } +- ++if (flag_t) + *structure = NULL; + return ASN1_SUCCESS; + } +-- +1.8.3.1 + diff --git a/CVE-2018-1000654.spec b/CVE-2018-1000654.spec deleted file mode 100644 index d0629c7460fc6fe3331b716c83b792f451ec9902..0000000000000000000000000000000000000000 --- a/CVE-2018-1000654.spec +++ /dev/null @@ -1,121 +0,0 @@ -From 9c40f7796c9d33179b602f65f4b587d175fba23c Mon Sep 17 00:00:00 2001 -From: Mike Gorse -Date: Thu, 11 Apr 2019 11:14:58 -0500 -Subject: [PATCH 1/2] _asn1_expand_object_id: Limit recursion - -Resolves #4 ---- - lib/parser_aux.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/lib/parser_aux.c b/lib/parser_aux.c -index 786ea64..08c2167 100644 ---- a/lib/parser_aux.c -+++ b/lib/parser_aux.c -@@ -675,7 +675,7 @@ _asn1_expand_object_id (asn1_node node) - { - asn1_node p, p2, p3, p4, p5; - char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1]; -- int move, tlen; -+ int move, tlen, tries; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; -@@ -684,6 +684,7 @@ _asn1_expand_object_id (asn1_node node) - - p = node; - move = DOWN; -+ tries = 0; - - while (!((p == node) && (move == UP))) - { -@@ -738,7 +739,9 @@ _asn1_expand_object_id (asn1_node node) - p4 = p4->right; - } - move = DOWN; -- continue; -+ tries++; -+ if (tries < 3) -+ continue; - } - } - } -@@ -747,6 +750,7 @@ _asn1_expand_object_id (asn1_node node) - else - move = RIGHT; - -+ tries = 0; - if (move == DOWN) - { - if (p->down) --- -From 57d6bc19d44b0693023031c6dbc0d21a36550f34 Mon Sep 17 00:00:00 2001 -From: Mike Gorse -Date: Thu, 25 Apr 2019 16:40:18 -0500 -Subject: [PATCH 2/2] Add reproducer for issues/4 to Test_tree.asn - ---- - tests/Test_tree.asn | 9 +++++++++ - tests/Test_tree_asn1_tab.c | 13 +++++++++++-- - 2 files changed, 20 insertions(+), 2 deletions(-) - -diff --git a/tests/Test_tree.asn b/tests/Test_tree.asn -index 0ad0dc5..a253bc8 100644 ---- a/tests/Test_tree.asn -+++ b/tests/Test_tree.asn -@@ -154,6 +154,15 @@ X520LocalityName ::= CHOICE { - bmpString BMPString } - - -+id-xnyTest OBJECT IDENTIFIER ::= {id-ix 29 1} -+id-ix OBJECR ::= {id-ix 29 2} -+BMPString ::= OCTET S -+} -+UniversalString : BY id O} -+id-ix OBJECT IDENTIFIER ::= {2 5} -+id-xnyTest OBJECT IDENTIFIER ::= {id-ix 29 1} -+anyTest2 ::= INTEGER -+ - id-Test OBJECT IDENTIFIER ::= {1 2 29 2} - - END -diff --git a/tests/Test_tree_asn1_tab.c b/tests/Test_tree_asn1_tab.c -index 7869f85..0f211c8 100644 ---- a/tests/Test_tree_asn1_tab.c -+++ b/tests/Test_tree_asn1_tab.c -@@ -68,7 +68,7 @@ const asn1_static_node Test_tree_asn1_tab[] = { - { "set", 1610612751, NULL }, - { NULL, 3, NULL }, - { "oid", 1073741836, NULL }, -- { "time2", 1082130449, NULL }, -+ { "time2", 1073741861, NULL }, - { "bol", 1073741828, NULL }, - { "oct", 1073741831, NULL }, - { "bit", 1073758214, NULL }, -@@ -81,7 +81,7 @@ const asn1_static_node Test_tree_asn1_tab[] = { - { "any", 1610637325, NULL }, - { NULL, 4104, "1"}, - { "gen", 1073758235, NULL }, -- { "time1", 16777233, NULL }, -+ { "time1", 36, NULL }, - { "SequenceTestTag", 1610612741, NULL }, - { "int1", 1610620931, NULL }, - { NULL, 2056, "2"}, -@@ -160,6 +160,15 @@ const asn1_static_node Test_tree_asn1_tab[] = { - { "universalString", 1073741856, NULL }, - { "utf8String", 1073741858, NULL }, - { "bmpString", 33, NULL }, -+ { "id-xnyTest", 1879048204, NULL }, -+ { NULL, 1073741825, "id-ix"}, -+ { NULL, 1073741825, "29"}, -+ { NULL, 1, "1"}, -+ { "id-ix", 1880096780, "OBJECR"}, -+ { NULL, 1073741825, "id-ix"}, -+ { NULL, 1073741825, "29"}, -+ { NULL, 1, "2"}, -+ { "BMPString", 1073741827, NULL }, - { "id-Test", 805306380, NULL }, - { NULL, 1073741825, "1"}, - { NULL, 1073741825, "2"}, --- -2.20.1 diff --git a/libtasn1.spec b/libtasn1.spec index da7087f1d46abfd37af228d08554eb6f65949fad..508a6b8d41a8fe0cccbec3e2dfe0ea811568e173 100644 --- a/libtasn1.spec +++ b/libtasn1.spec @@ -1,7 +1,7 @@ Summary: Libtasn1 is a ASN.1 parsing library Name: libtasn1 Version: 4.13 -Release: 7 +Release: 8 # The libtasn1 library is LGPLv2+, utilities are GPLv3+ License: GPLv3+ and LGPLv2+ @@ -9,7 +9,13 @@ URL: http://www.gnu.org/software/libtasn1/ Source0: http://ftp.gnu.org/gnu/libtasn1/%name-%version.tar.gz Source1: http://ftp.gnu.org/gnu/libtasn1/%name-%version.tar.gz.sig -Patch0000: CVE-2018-1000654.spec +Patch0000: 0001-Fix-endless-loop-in-_asn1_check_identifier.patch +patch0001: 0002-_asn1_expand_object_id-Limit-recursion.patch +Patch0002: 0003-_asn1_add_static_node-made-thread-safe.patch +Patch0003: 0004-_asn1_expand_object_id-fix-memory-leak-on-error.patch +Patch0004: 0005-Fix-two-memleaks-in-asn1_array2tree.patch +Patch0005: 0006-Fix-memleaks-in-asn1_array2tree.patch +Patch0006: 0007-fix-memleaks-in-asn1-arrat2tree.patch BuildRequires: gcc, autoconf, automake, libtool, gnupg2, bison, pkgconfig, help2man, valgrind-devel Provides: bundled(gnulib) = 20130324 @@ -80,6 +86,9 @@ test "$1" = 0 -a -f %_infodir/%name.info.gz && \ %{_infodir}/*.info.* %changelog +* Sat Jun 6 2020 liquor - 4.13-8 +- Fix fuzz issues + * Fri Mar 20 2020 wangye - 4.13-7 - Fix CVE-2018-1000654