Hi Holger,
first, thank you very much for such a detailed bug report ! At first it looked impossible to me because there are tests everywhere to ensure that the last arg points to a null string.
But after a more careful read, I think I have found the issue.
Here in cfgparse.c, we iterate over the parameters :
3633 arg = 0; 3634 args[arg] = line; 3635 3636 while (*line && arg < MAX_LINE_ARGS) {...
And here we ensure that we set the last arg to point to the last char of the line :
3700 /* zero out remaining args and ensure that at least one entry 3701 * is zeroed out. 3702 */ 3703 while (++arg <= MAX_LINE_ARGS) { 3704 args[arg] = line; 3705 }
But this is wrong for two reasons :
In fact the test would be valid if we could ensure that *line = 0 in case of truncated line. Also it would be wise to report it because as you tell it, you don't know if your configuration is working or not. So let's reject the line and indicate where it broke.
The following patch fixes it.
Thanks!
Willy
From 3b39c1446b9bd842324e87782a836948a07c25a2 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w#1wt.eu>
Date: Mon, 9 Nov 2009 21:16:53 +0100
Subject: [BUG] config: fix wrong handling of too large argument count
Holger Just reported that running ACLs with too many args caused a segfault during config parsing. This is caused by a wrong test on argument count. In case of too many arguments on a config line, the last one was not correctly zeroed. This is now done and we report the error indicating what part had been truncated.
--- src/cfgparse.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/src/cfgparse.c b/src/cfgparse.c index f0d690b..a1d2428 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -3697,6 +3697,21 @@ int readcfgfile(const char *file) if (!**args) continue; + if (*line) { + /* we had to stop due to too many args. + * Let's terminate the string, print the offending part then cut the + * last arg. + */ + while (*line && *line != '#' && *line != '\n' && *line != '\r') + line++; + *line = '\0'; + + Alert("parsing [%s:%d]: line too long, truncating at word %d, position %d : <%s>.\n", + file, linenum, arg + 1, args[arg] - thisline + 1, args[arg]); + err_code |= ERR_ALERT | ERR_FATAL; + args[arg] = line; + } + /* zero out remaining args and ensure that at least one entry * is zeroed out. */ -- 1.6.4.4Received on 2009/11/09 21:19
This archive was generated by hypermail 2.2.0 : 2009/11/09 21:30 CET