<div>There is a heap overflow in "read_file". It can be triggered if the file it wants to read is not a valid conf file and it has very long name. Notice that it can also be trigger through function "clear_cache_and_reload" which is called in some event handlers. So it might be able to be triggered remotely(do not have a poc).</div><br><div>poc(target: <a href="https://link.getmailspring.com/link/FC759E02-CF53-4055-ABFC-17B29107897F@getmailspring.com/0?redirect=git%3A%2F%2Fthekelleys.org.uk%2Fdnsmasq.git&recipient=ZG5zbWFzcS1kaXNjdXNzQGxpc3RzLnRoZWtlbGxleXMub3JnLnVr" title="git://thekelleys.org.uk/dnsmasq.git">git://thekelleys.org.uk/dnsmasq.git</a>, commit: e24abf28a29574069717af78c1d3e0ede64388ff, compilation command: CC="clang -fsanitize=address" make):</div><div>folder=$(python -c "print(('B'*100+'/')*10)"); mkdir -p $folder && echo "111" > $folder/config && ./dnsmasq -p 8333 -C $folder/config -d</div><br><div>The bug is in line 4586 of options.c.</div><div>Here is the snippet :</div><div>-------</div><div>    oops:</div><div>      if (errmess)</div><div>  strcpy(daemon->namebuff, errmess);</div><div>      </div><div>      if (errmess || !one_opt(option, arg, daemon->namebuff, _("error"), 0, hard_opt == LOPT_REV_SERV))</div><div>      {</div><div>          sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"), lineno, file);</div><div>         if (hard_opt != 0)</div><div>            my_syslog(LOG_ERR, "%s", daemon->namebuff);</div><div>        else</div><div>          die("%s", daemon->namebuff, EC_BADCONF);</div><div> }</div><div>--------</div><div>Analysis:</div><div>If oops is triggered, an error message will be copied into the daemon->namebuff. And then a sprintf will be triggered to append a detailed error message.</div><div>However, the namebuff is of length MAXDNAME and file is also of length MAXDNAME. So, overflow happens.</div><br><div>Suggested fix:</div><div>------</div><div>diff --git a/src/option.c b/src/option.c</div><div>index 83d57a6..24e77e4 100644</div><div>--- a/src/option.c</div><div>+++ b/src/option.c</div><div>@@ -4583,7 +4583,8 @@ static void read_file(char *file, FILE *f, int hard_opt)</div><div>          </div><div>       if (errmess || !one_opt(option, arg, daemon->namebuff, _("error"), 0, hard_opt == LOPT_REV_SERV))</div><div>        {</div><div>-         sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"), lineno, file);</div><div>+         size_t buf_len = strlen(daemon->namebuff);</div><div>+         snprintf(daemon->namebuff + buf_len, MAXDNAME-buf_len, _(" at line %d of %s"), lineno, file);</div><div>          if (hard_opt != 0)</div><div>            my_syslog(LOG_ERR, "%s", daemon->namebuff);</div><div>          else</div><div>------</div><br><div>Yihui Zeng</div><img class="mailspring-open" alt="Sent from Mailspring" width="0" height="0" style="border:0; width:0; height:0;" src="https://link.getmailspring.com/open/FC759E02-CF53-4055-ABFC-17B29107897F@getmailspring.com?me=b6032978&recipient=ZG5zbWFzcS1kaXNjdXNzQGxpc3RzLnRoZWtlbGxleXMub3JnLnVr">