[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