[rrd-developers] Bug#573638: rrdtool: rrdcgi crashes at printlasttime()

Tobias Oetiker tobi at oetiker.ch
Sun Mar 14 15:06:02 CET 2010


Hi Robert,

in 2012:2013 I put in the patch below ... this should provide a
more generic fix for the problem. rrd_cgi functions all used to
fail horribly when a librrd function tried to touch ARGV[0] (mostly
to print an errror message including the name name of the calling
program) ...

obviously an even better fix would be to remove the whole argv
magic from rrd_cgi ... but this patch would be rather substantial.

cheers
tobi

--- rrd_cgi.c   (revision 2012)
+++ rrd_cgi.c   (working copy)
@@ -1053,7 +1053,7 @@
     int       curarg_contains_rrd_directives;

     /* local array of arguments while parsing */
-    int       argc = 0;
+    int       argc = 1;
     char    **argv;

 #ifdef DEBUG_PARSER
@@ -1069,6 +1069,7 @@
     if (!argv) {
         return NULL;
     }
+    argv[0] = "rrdcgi";

     /* skip leading blanks */
     while (isspace((int) *line)) {
@@ -1172,7 +1173,7 @@
         argv[argc - 1] = rrd_expand_vars(stralloc(argv[argc - 1]));
     }
 #ifdef DEBUG_PARSER
-    if (argc > 0) {
+    if (argc > 1) {
         int       n;

         printf("<-- arguments found [%d]\n", argc);
@@ -1186,9 +1187,18 @@
 #endif

     /* update caller's notion of the argument array and it's size */
-    *arguments = argv;
-    *argument_count = argc;

+    /* note this is a bit of a hack since the rrd_cgi code used to just put
+       its arguments into a normal array starting at 0 ... since the rrd_*
+       commands expect and argc/argv array we used to just shift everything
+       by -1 ... this in turn exploded when a rrd_* function tried to print
+       argv[0] ... hence we are now doing everything in argv style but hand
+       over seemingly the old array ... but doing argv-1 will actually end
+       up in a 'good' place now. */
+
+    *arguments = argv+1;
+    *argument_count = argc-1;
+
     if (Quote) {
         return NULL;
     }
@@ -1241,7 +1251,7 @@
     if (end) {
         /* got arguments, call function for 'tag' with arguments */
         val = func(argc, (const char **) args);
-        free(args);
+        free(args-1);
     } else {
         /* unable to parse arguments, undo 0-termination by scanargs */
         for (; argc > 0; argc--) {

at Today Sebastian Harl wrote:

> Hi Robert,
>
> On Thu, Mar 11, 2010 at 01:34:01PM +0100, Robert Luberda wrote:
> > iptotal.cgi (from the iptotal package) contains the following line
> > <RRD::TIME::LAST /var/lib/iptotal/iptotal.rrd %c>
> > which causes rrdcgi to crash with the following backtrace:
> >
> > (gdb) bt
> > #0  strlen () at ../sysdeps/i386/i486/strlen.S:40
> > #1  0xb73a681e in _IO_vfprintf_internal (s=0xbfa4086c,
> >     format=0xb781edd0 "Usage: rrdtool %s [--daemon <addr>] <file>",
> > ap=0xbfa40988 "\021\001\202?")
> >     at vfprintf.c:1601
> > #2  0xb73c56b4 in _IO_vsnprintf (string=0xb78269c0 "Usage: rrdtool ",
> > maxlen=4096,
> >     format=0xb781edd0 "Usage: rrdtool %s [--daemon <addr>] <file>",
> > args=0xbfa40984 "\211")
> >     at vsnprintf.c:120
> > #3  0xb78140c4 in rrd_set_error () from /usr/lib/librrd.so.4
> > #4  0xb7805be4 in rrd_last () from /usr/lib/librrd.so.4
> > #5  0x0804b211 in printtimelast ()
> > #6  0x0804aa83 in ?? ()
> > #7  0x0804c265 in ?? ()
> > #8  0xb737bb55 in __libc_start_main (main=0x804bf70, argc=2,
> > ubp_av=0xbfa40bb4, init=0x804c5c0,
> >     fini=0x804c5b0, rtld_fini=0xb78629b0 <_dl_fini>,
> > stack_end=0xbfa40bac) at libc-start.c:222
>
> Thanks for reporting this!
>
> > Afer some investigation, I found that the problem is in the line 991
> > of rrd_cgi.c:
> >
> >   last = rrd_last(argc + 1, (char **) args - 1);
> >
> > The first argument of rrd_last() should obviously be argc (which is 2),
> > not argc + 1.  Also please note that second argument of the function
> > refers to address before the start of the array, which seems to
> > be a very bad programming style, and which in fact is a root cause of the
> > crash as rrd_last() tries to display argv[0] in an error message.
>
> Ouch! What an ugly hack ?
>
> > The attached patch fixes the problem.
>
> Thanks for tracing that back and providing a patch! Imho, the patch
> looks fine. With this E-mail, I'm forwarding the issue and the patch
> upstream, hoping for inclusion in the upstream SVN. I'll upload a fixed
> package to Debian soonish.
>
> Cheers,
> Sebastian
>
>

-- 
Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
http://it.oetiker.ch tobi at oetiker.ch ++41 62 775 9902 / sb: -9900



More information about the rrd-developers mailing list