[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: Re: sh (pid 1081) segfaults for page address 00000000 at pc 00000000
From: Denys Vlasenko <vda.linux () googlemail ! com>
Date: 2009-01-31 14:04:02
Message-ID: 200901311504.02160.vda.linux () googlemail ! com
[Download RAW message or body]
On Saturday 31 January 2009 12:11, Cristian Ionescu-Idbohrn wrote:
> CONFIG_EXTRA_COMPAT=y
> CONFIG_FEATURE_BUFFERS_GO_IN_BSS=y
Try EXTRA_COMPAT off and FEATURE_BUFFERS_USE_MALLOC=y.
To be honest, I always use FEATURE_BUFFERS_USE_MALLOC,
thus FEATURE_BUFFERS_GO_IN_BSS might have bugs.
> CONFIG_SHOW_USAGE=y
> CONFIG_FEATURE_VERBOSE_USAGE=y
> CONFIG_FEATURE_COMPRESS_USAGE=y
> CONFIG_GETOPT_LONG=y
> CONFIG_FEATURE_PIDFILE=y
> CONFIG_FEATURE_SUID=y
I think you can turn these off, but this unlikely to be relevant.
> CONFIG_FEATURE_PREFER_APPLETS=y
Interesting, this might be relevant. Try turning it off.
> CONFIG_FEATURE_EDITING=y
Unlikely, but try turning it off.
> CONFIG_ASH_ALIAS=y
> CONFIG_ASH_MATH_SUPPORT=y
> CONFIG_ASH_GETOPTS=y
> CONFIG_ASH_CMDCMD=y
> CONFIG_ASH_RANDOM_SUPPORT=y
Try turning these off one-by-one, and test after each.
> (gdb) bt full
> #0 0x000853ee in segv_handler (signal_number=0)
> at .../busybox-1.13.2/shell/ash.c:3302
> No locals.
> #1 <signal handler called>
> No symbol table info available.
> #2 0x00000000 in ?? ()
> No symbol table info available.
> #3 0x00084202 in stack_nputstr (s=0x0, n=618808, p=0xafc9d "on")
> at .../busybox-1.13.2/shell/ash.c:1474
> No locals.
> #4 0x000a3a42 in ?? ()
> No symbol table info available.
> Backtrace stopped: frame did not save the PC
> (gdb) frame 3
> #3 0x00084202 in stack_nputstr (s=0x0, n=618808, p=0xafc9d "on")
> at .../busybox-1.13.2/shell/ash.c:1474
> 1474 p = (char *)memcpy(p, s, n) + n;
> (gdb) l
> 1469
> 1470 static char *
> 1471 stack_nputstr(const char *s, size_t n, char *p)
> 1472 {
> 1473 p = makestrspace(n, p);
> 1474 p = (char *)memcpy(p, s, n) + n;
gdb says that s is NULL here, and n is very large.
> 1475 return p;
> 1476 }
Let's see how that could happen. stack_nputstr has only 2 callsites.
This one can't be it, strlen(NULL) would segfault (on x86,
can you confirm is it true on your arch too?) -
static char *
stack_putstr(const char *s, char *p)
{
return stack_nputstr(s, strlen(s), p);
}
Another callsite is in argstr(), which "Performs variable and command
substitution". Sounds about right!
It's here:
....
if (flag & EXP_TILDE) {
char *q;
flag &= ~EXP_TILDE;
tilde:
q = p;
if (*q == CTLESC && (flag & EXP_QWORD))
q++;
if (*q == '~')
p = exptilde(p, q, flag);
}
start:
startloc = expdest - (char *)stackblock();
for (;;) {
length += strcspn(p + length, reject);
c = p[length];
if (c && (!(c & 0x80)
#if ENABLE_ASH_MATH_SUPPORT
|| c == CTLENDARI
#endif
)) {
/* c == '=' || c == ':' || c == CTLENDARI */
length++;
}
if (length > 0) {
int newloc;
if (p==NULL) bb_error_msg("p is NULL at %d!", __LINE__)
========> expdest = stack_nputstr(p, length, expdest);
and code is sufficiently scary to not even try to understand it
quickly. For one, p is assigned in multiple places and goto's
can bring you back to tilde: and start: labels.
Can you add some debugging along the lines of
if (p==NULL) bb_error_msg("p is NULL at %d!", __LINE__)?
I added one in the example above, but feel free to add
similar lines in other places too, for example,
on entry to argstr() itself, after each p = ... assignment
and before length += strcspn(....) line. Etc.
Also it's interestng to find out how "length" var ended up
with huge value of 618808. Can you add
if (length>9999) bb_error_msg("length=%d, p=%p at %d!", (int)length, p, __LINE__)
after length += strcspn(...)?
Let me know what do you see.
--
vda
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic