Bug 3679 - uClibc with crosstool-ng builds buggy busybox (argument / parameter problem)
Summary: uClibc with crosstool-ng builds buggy busybox (argument / parameter problem)
Status: RESOLVED WORKSFORME
Alias: None
Product: uClibc
Classification: Unclassified
Component: Other (show other bugs)
Version: 0.9.30.2
Hardware: PC Linux
: P4 major
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-01 01:11 UTC by John
Modified: 2012-08-25 02:49 UTC (History)
1 user (show)

See Also:
Host: i486-linux
Target: i486-linux
Build: i486-linux


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John 2011-05-01 01:11:29 UTC
When building busybox 1.18.4 with crosstool-ng 1.10.1 and uClibc 0.9.30.2 building GCC 4.2.4, busybox compiled to use hush improperly passes parameters to applets.
Example:
if you type 'busybox ls', it passes 'ls' as a argument to the applet 'ls' effectivly making it 'busybox ls ls'. Similarly 'busybox mount' passes 'mount' to mount. Linking busybox to 'ls' and calling 'ls' still exhibits the problem. This problem makes many applets malfunction. It is probably putting what should be in argv[0] into argv[1].
Comment 1 Bernhard Reutner-Fischer 2011-05-01 12:36:57 UTC
4.2.x is too buggy. Also, please use the current stable release (with 4.5.x)
Comment 2 John 2011-05-03 22:55:25 UTC
Waiting for rebuild (again)
It built a broken 4.5 compiler so I am trying 4.4
Comment 3 John 2011-05-06 18:49:50 UTC
Couldn't build a 4.5.x compiler but I built a 4.4.x compiler and the bug still exists.
"/busybox ls" == "/busybox ls ls"
Comment 4 Bernhard Reutner-Fischer 2011-05-06 20:14:09 UTC
So what do you see for:
cd /tmp
rm -f ls
ln -s /busybox ls
./ls -l
Comment 5 John 2011-05-06 21:10:47 UTC
(In reply to comment #4)
> So what do you see for:
> cd /tmp
> rm -f ls
> ln -s /busybox ls
> ./ls -l
/ # cd /tmp
/ # rm -f ls
Cannot remove ls: No such file or directory
/ # ln -s /busybox ls
/ # ./ls -l
ls: -l: No such file or directory
/bin/ls
/ #
Comment 6 John 2011-05-06 21:15:20 UTC
(In reply to comment #4)
> So what do you see for:
> cd /tmp
> rm -f ls
> ln -s /busybox ls
> ./ls -l
/ # cd /tmp
/ # rm -f ls
Cannot remove ls: No such file or directory
/ # ln -s /busybox ls
/ # ./ls -l
ls: -l: No such file or directory
./ls
/ # 

^^ Updated - I made a mistake copying from qemu
Comment 7 John 2011-05-07 19:05:37 UTC
Would a video of the offending bug help?
Comment 8 Bernhard Reutner-Fischer 2011-05-07 22:47:56 UTC
No, but ldd and strace output (assuming you do them with 0.9.31 or master).
Comment 9 John 2011-05-08 23:42:21 UTC
(In reply to comment #8)
> No, but ldd and strace output (assuming you do them with 0.9.31 or master).

Sorry, do not know how to use strace
$ ldd busybox
Checking sub-depends for '/usr/lib/libcrypt.so.0'
Checking sub-depends for '/usr/lib/uClibc.so.0'
        libcrypt.so.0 => /usr/lib/libcrypt.so.0 (0x00000000)
        uClibc.so.0 => /usr/lib/uClibc.so.0 (0x00000000)
        /lib/ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x00000000)
$
^^ Isn't all zeros for the address alittle odd?
Comment 10 John 2011-05-13 01:25:22 UTC
Any suggestions?
Comment 11 John 2011-05-14 04:50:36 UTC
Here is a workaround patch
Apply to ./libbb/appletlib.c:
*** appletlib.c      2011-05-13 21:40:36.000000000 -0700
--- appletlib/c 2011-05-13 21:35:03.000000000 -0700
*************** void FAST_FUNC run_applet_no_and_exit(in
*** 763,769 ****
        }
        if (ENABLE_FEATURE_SUID) 
                check_suid(applet_no);
!       exit(applet_main[applet_no](argc, argv));
  }

  void FAST_FUNC run_applet_and_exit(const char *name, char **argv)
--- 763,769 ----
        }
        if (ENABLE_FEATURE_SUID)
                check_suid(applet_no);
!       exit(applet_main[applet_no](argc, argv+1));
  }

  void FAST_FUNC run_applet_and_exit(const char *name, char **argv)
Comment 12 John 2011-05-14 05:42:12 UTC
Issue though.
It causes it to Segmentation fault even more. (Randomly...Was doing it before, just not as much)
Comment 13 John 2012-08-25 02:49:10 UTC
I managed to find the core of the problem.
uClibc poses itself as glibc and defines __GLIBC__.
This causes the #ifdef __GLIBC__ to evaluate to true and resets optind to zero instead of one.
Unfortunately the uClibc getopt() is BSD style and pukes and keeps optind at zero.
Putting an exception for uClibc in 
libbb/getopt32.c
libbb/vfork_daemon_rexec.c
shell/shell_common.c
util-linux/getopt.c

fixed the problem.