From 9a8bd90d2f9beffba267c91b0a9d37aefcc2836e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 4 Apr 2024 16:21:52 +0200 Subject: [PATCH] auth: Fix memory leaks in the bind file format parser Some tokens were not properly freed: ACL names and entries, unused word or quoted string terms. This is limited to the parsing of the bind file format, zones themselves are fine, so there is no security impact. Found by LeakSanitizer over our existing unit tests. --- pdns/bindparser.yy | 48 +++++++++++++++++++++++++------------- pdns/named.conf.parsertest | 9 +++++++ 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/pdns/bindparser.yy b/pdns/bindparser.yy index 179ca45761..7b9e49eda9 100644 --- a/pdns/bindparser.yy +++ b/pdns/bindparser.yy @@ -17,7 +17,7 @@ extern int yydebug; #define YYSTYPE char * -extern "C" +extern "C" { int yyparse(void); int yylex(void); @@ -35,7 +35,7 @@ const char *bind_directory; extern int linenumber; static void yyerror(const char *str) { - extern char *current_filename; + extern char *current_filename; throw PDNSException("Error in bind configuration '"+string(current_filename)+"' on line "+std::to_string(linenumber)+": "+str); } @@ -44,7 +44,7 @@ static BindParser *parent; BindDomainInfo s_di; void BindParser::parse(const string &fname) -{ +{ yydebug=0; yyin=fopen(fname.c_str(),"r"); yyrestart(yyin); @@ -113,7 +113,7 @@ void BindParser::commit(BindDomainInfo DI) %% root_commands: - | + | root_commands root_command SEMICOLON ; @@ -126,7 +126,7 @@ commands: ; command: - terms + terms ; global_zone_command: @@ -137,7 +137,7 @@ global_zone_command: parent->commit(s_di); s_di.clear(); } - | + | ZONETOK quotedname AWORD zone_block { s_di.name=DNSName($2); @@ -156,19 +156,26 @@ global_options_command: acl_command: - ACLTOK quotedname acl_block | ACLTOK filename acl_block + ACLTOK quotedname acl_block + { + free($2); + } + | ACLTOK filename acl_block ; acl_block: OBRACE acls EBRACE ; - -acls: + +acls: | acl SEMICOLON acls ; acl: AWORD + { + free($1); + } ; options_commands: @@ -189,10 +196,10 @@ options_directory_command: DIRECTORYTOK quotedname } ; -also_notify_command: ALSONOTIFYTOK OBRACE also_notify_list EBRACE +also_notify_command: ALSONOTIFYTOK OBRACE also_notify_list EBRACE ; -also_notify_list: +also_notify_list: | also_notify SEMICOLON also_notify_list ; @@ -208,10 +215,17 @@ terms: /* empty */ terms term ; -term: AWORD | block | quotedname +term: AWORD + { + free($1); + } + | block | quotedname + { + free($1); + } ; -block: - OBRACE commands EBRACE +block: + OBRACE commands EBRACE ; zone_block: @@ -252,7 +266,7 @@ zone_also_notify: AWORD ; primaries: /* empty */ - | + | primaries primary SEMICOLON ; @@ -266,7 +280,6 @@ primary: AWORD zone_file_command: FILETOK quotedname { - // printf("Found a filename: '%s'\n",$2); s_di.filename=$2; free($2); } @@ -289,4 +302,7 @@ quotedname: ; filename: AWORD + { + free($1); + } ; diff --git a/pdns/named.conf.parsertest b/pdns/named.conf.parsertest index b8b0e35993..5f2756ebc6 100644 --- a/pdns/named.conf.parsertest +++ b/pdns/named.conf.parsertest @@ -1,6 +1,15 @@ # this file is used by ../pdns/test-bindparser_cc.cc # if you change it, please make check! +acl bogusnets { + 0.0.0.0/8; 192.0.2.0/24; 224.0.0.0/3; + 10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16; +}; + +acl "not-these-ips" { + !192.168.0/24;!10.0/16;any; +}; + options { directory "./zones/"; recursion no; -- 2.47.2