[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: 4.0 core dump from printf -v foo %s b
From: |
Chet Ramey |
Subject: |
Re: 4.0 core dump from printf -v foo %s b |
Date: |
Wed, 11 Nov 2009 21:41:29 -0500 |
User-agent: |
Thunderbird 2.0.0.23 (Macintosh/20090812) |
Greg Wooledge wrote:
> The other two messages I sent today were just things I encountered while
> bringing my bash 4.0 up to the current patch level. This is the real
> problem I've been chasing.
>
> imadev:/var/tmp/bash-4.0$ bash-3.1.17 -c 'printf -v foo %s bar'
> imadev:/var/tmp/bash-4.0$ bash-4.0.10 -c 'printf -v foo bar'
> imadev:/var/tmp/bash-4.0$ bash-4.0.10 -c 'printf -v foo %s bar'
> Segmentation fault (core dumped)
> imadev:/var/tmp/bash-4.0$ ./bash --version | head -1
> GNU bash, version 4.0.35(2)-release (hppa2.0-hp-hpux10.20)
> imadev:/var/tmp/bash-4.0$ ./bash -c 'printf -v foo bar'
> imadev:/var/tmp/bash-4.0$ ./bash -c 'printf -v foo %s bar'
> Segmentation fault (core dumped)
>
> I looked into printf.def using gdb, but I only partially understand
> what's happening. I don't understand why this works on other platforms
> but fails on HP-UX 10.20, but maybe that's my ignorance....
The behavior depends on the behavior of vsnprintf.
>
> In the "printf -v foo bar" case, there's no format specifier with a
> percent sign. So, even though the vbuf variable is never initialized
> beforehand, the first macro that it calls is PC, which calls vbadd,
> which allocates space for vbuf.
>
> In the "printf -v foo %s bar" case, vbuf is still not initialized,
> but the first macro that gets called is PF. PF calls vbprintf, which
> calls vsnprintf (vbuf + vblen, ....) but vbuf is still NULL.
>
> If my understanding is correct, the vbprintf function either needs to
> do the nlen vs. vbsize check before calling vsnprintf(vbuf+...), or
> it needs to call vsnprintf with a locally allocated buffer first, and
> then copy the result into vbuf once it's been resized.
This is where the behavior depends on vsnprintf. The idea is that you
pass vsnprintf the currently-allocated size of vbuf (vbsize) less what
you've already written (vblen) as its `len' argument. That's the number
of characters currently available in the buffer. vsnprintf is guaranteed
to write no more than that number of characters to the buffer that's
passed, and in addition to return the number of character that would have
been written if the `len' argument had been large enough.
Once you find out how many characters you need, you make sure the buffer
is big enough and go on. So far, so good.
Since the `len' argument in your example is 0, vsnprintf should write no
characters into the buffer and return the number of characters that would
have been required. The check performs as desired, the buffer is
allocated, and the vsnprintf is called again with the appropriately-sized
buffer.
If your version of vsnprintf doesn't behave like that, I claim it's a
bug. The Posix and C standards explicitly allow the buffer to be NULL
if the size argument is 0, and guarantee that no data will be written
in this case.
Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU chet@case.edu http://cnswww.cns.cwru.edu/~chet/