[PATCH] ping6: segfault on incorrect command line
walter harms
wharms at bfs.de
Thu Nov 19 15:23:45 UTC 2009
Michael Abbott schrieb:
> On Thu, 19 Nov 2009, walter harms wrote:
>> Michael Abbott schrieb:
>>> On Wed, 18 Nov 2009, Leonid Lisovskiy wrote:
>>>> ping6 segfaults on incorrect command line in case of busybox linked
>>>> against uClibc 0.9.30.1 example:
>>>>
>>>> $ ping6 -Z google.com
>>>> Segmentation fault
>>>>
>>>> Seems to be this happens due to uClibc don't initialize argv[-1] at
>>>> all. Simple patch is below:
>>>> --- a/networking/ping.c 2009-09-26 17:14:57.000000000 +0400
>>>> +++ a/networking/ping.c 2009-11-18 20:39:19.000000000 +0300
>>>> @@ -769,6 +769,7 @@ int ping_main(int argc UNUSED_PARAM, cha
>>>> int ping6_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
>>>> int ping6_main(int argc UNUSED_PARAM, char **argv)
>>>> {
>>>> + argv[-1] = argv[0];
>>>> argv[0] = (char*)"-6";
>>>> return ping_main(0 /* argc+1 - but it's unused anyway */,
>>>> argv - 1);
>>> Is argv[-1] even a valid address? Surely you're overwriting unknown
>>> memory here, with entirely unpredictable consequences?
>>>
>>> Or is this argv defined elsewhere to extend into negative offsets?
>>> If you're saying it's come from uClibc I doubt it, in which case the
>>> bug has to be passing argv-1 to ping_main.
>> I guess the basic idea is to rewrite
>> ping6 arg -> ping -6 arg
>>
>> ping: usage.h: -4, -6 Force IPv4 or IPv6 hostname resolution
>
> I guess so. Looks as if the trick is just a little bit *too* cute,
> though: somebody's trying to add extra storage to an array (argv[]) that
> doesn't have room for it!
>
> Solutions: 1. alloca() a copy of argv, or use a dynamically sized array
> (pity that argc is undefined ... or can we actually rely on it here) and
> make room for the extra parameter: is this proper busybox style? Not sure
> about alloca in restricted environments, and my alloca(3) man page
> deprecates it!
>
> 2. Refactor ping_main and ping6_main to share a common routine with an
> extra flag.
>
> Sorry, I'm not so familiar with the innards of busybox. Looks like this
> trick goes a fair way back, so maybe there's some reason for believing it
> should work?
>
I think it worked because the original was simply:
argv[0] = (char*)"-6";
the argv[-1] trick is a loop to much by using the wrong memory
the ping_main has this trick here:
#if ENABLE_PING6
while ((++argv)[0] && argv[0][0] == '-') { <-- so the argv-1 is important for ping6
if (argv[0][1] == '4') {
af = AF_INET;
continue;
}
if (argv[0][1] == '6') {
af = AF_INET6;
continue;
}
bb_show_usage();
}
#else
argv++;
#endif
@leonid:
i can not reproduce your problem, what version of bb do you use ?
./busybox ping6 -Z google.com
BusyBox v1.15.0 (2009-11-19 16:17:14 CET) multi-call binary
Usage: ping6 host
Send ICMP ECHO_REQUEST packets to network hosts
More information about the busybox
mailing list