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).
poc(target: git://thekelleys.org.uk/dnsmasq.git
(https://link.getmailspring.com/link/[email protected]/0?redirect=git%3A%2F%2Fthekelleys.org.uk%2Fdnsmasq.git&recipient=ZG5zbWFzcS1kaXNjdXNzQGxpc3RzLnRoZWtlbGxleXMub3JnLnVr),
commit: e24abf28a29574069717af78c1d3e0ede64388ff, compilation command:
CC="clang -fsanitize=address" make):
folder=$(python -c "print(('B'*100+'/')*10)"); mkdir -p $folder && echo "111" >
$folder/config && ./dnsmasq -p 8333 -C $folder/config -d
The bug is in line 4586 of options.c.
Here is the snippet :
-------
oops:
if (errmess)
strcpy(daemon->namebuff, errmess);
if (errmess || !one_opt(option, arg, daemon->namebuff, _("error"), 0, hard_opt
== LOPT_REV_SERV))
{
sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"),
lineno, file);
if (hard_opt != 0)
my_syslog(LOG_ERR, "%s", daemon->namebuff);
else
die("%s", daemon->namebuff, EC_BADCONF);
}
--------
Analysis:
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.
However, the namebuff is of length MAXDNAME and file is also of length
MAXDNAME. So, overflow happens.
Suggested fix:
------
diff --git a/src/option.c b/src/option.c
index 83d57a6..24e77e4 100644
--- a/src/option.c
+++ b/src/option.c
@@ -4583,7 +4583,8 @@ static void read_file(char *file, FILE *f, int hard_opt)
if (errmess || !one_opt(option, arg, daemon->namebuff, _("error"), 0, hard_opt
== LOPT_REV_SERV))
{
- sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"),
lineno, file);
+ size_t buf_len = strlen(daemon->namebuff);
+ snprintf(daemon->namebuff + buf_len, MAXDNAME-buf_len, _(" at line %d of
%s"), lineno, file);
if (hard_opt != 0)
my_syslog(LOG_ERR, "%s", daemon->namebuff);
else
------
Yihui Zeng_______________________________________________
Dnsmasq-discuss mailing list
[email protected]
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss