Package: libpopt-dev Version: 1.7-5 Severity: important Tags: patch Hi,
it seems like poptStuffArgs() hasn't been tested very thoroughly. If used twice with the same context, it will invariably cause memory corruption and possibly memory leaks or a crash. The proper fix is to change the allocation of leftOvers so it adapts to the input on the fly instead of trying to pre-allocate it in one go. Patch attached. Cheers, Richard -- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (500, 'unstable') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.11-1-686 Locale: LANG=sv_SE, LC_CTYPE=sv_SE (charmap=ISO-8859-1) Versions of packages libpopt-dev depends on: ii libc6-dev [libc-dev] 2.3.2.ds1-22 GNU C Library: Development Librari ii libpopt0 1.7-5 lib for parsing cmdline parameters libpopt-dev recommends no packages. -- no debconf information
--- popt.c +++ popt.c @@ -168,7 +168,8 @@ if (!(flags & POPT_CONTEXT_KEEP_FIRST)) con->os->next = 1; /* skip argv[0] */ - con->leftovers = calloc( (argc + 1), sizeof(*con->leftovers) ); + con->allocLeftovers = argc + 1; + con->leftovers = calloc( con->allocLeftovers, sizeof(*con->leftovers) ); /[EMAIL PROTECTED] [EMAIL PROTECTED]/ /* FIX: W2DO? */ con->options = options; /[EMAIL PROTECTED] [EMAIL PROTECTED]/ @@ -742,7 +743,19 @@ return 0; } if (con->leftovers != NULL) /* XXX can't happen */ - con->leftovers[con->numLeftovers++] = origOptString; + /* One might think we can never overflow the leftovers + array. Actually, that's true, as long as you don't + use poptStuffArgs()... */ + if ((con->numLeftovers + 1) >= (con->allocLeftovers)) { + con->allocLeftovers += 10; + con->leftovers = + realloc(con->leftovers, + sizeof(*con->leftovers) * con->allocLeftovers); + } + con->leftovers[con->numLeftovers++] + = xstrdup(origOptString); /* so a free of a stuffed + argv doesn't give us a + dangling pointer */ continue; } @@ -1076,7 +1089,11 @@ } con->execs = _free(con->execs); + for (i = 0; i < con->numLeftovers; i++) { + con->leftovers[i] = _free(&con->leftovers[i]); + } con->leftovers = _free(con->leftovers); + con->finalArgv = _free(con->finalArgv); con->appName = _free(con->appName); con->otherHelp = _free(con->otherHelp); --- poptint.h +++ poptint.h @@ -65,6 +65,7 @@ /[EMAIL PROTECTED]@*/ /[EMAIL PROTECTED]@*/ const char ** leftovers; int numLeftovers; + int allocLeftovers; int nextLeftover; /[EMAIL PROTECTED]@*/ const struct poptOption * options;