Re: interesting segfault when running awk as pid==1

2012-07-07 Thread Michael Tokarev
On 07.07.2012 23:33, Denys Vlasenko wrote:
[]
 The debian-specific patch in question is this (one-liner):

 shell/ash.c:
 -   { VSTRFIXED|VTEXTFIXED   , bb_PATH_root_path, changepath },
 +   { VSTRFIXED|VTEXTFIXED|VEXPORT, bb_PATH_root_path, changepath },

 so it merely exports PATH variable, and should not affect
 the behavour in question, but I'm not sure anymore about
 this.  It looks rather innocent.

 Apparently, it makes it so that ash exports $PATH.
 If $PATH was in the set of inherited variables,
 then it is reused, and this apparently works.
 But in init, $PATH may be _not_ inherited.
 So ash sets its own $PATH (I just tested it):

 PATH=/sbin:/usr/sbin:/bin:/usr/bin

 Basically, these two scenarios are not exactly the same.

 Try reproducing segfault by running ahs with empty environment:

 env - /path/to/busybox ash

 Does it segfault if you run awk from it?
 
 Reproduced.
 
 if (environ) for (envp = environ; *envp; envp++) {
 /* environ is writable, thus we don't strdup it needlessly */
 char *s = *envp;
 char *s1 = strchr(s, '=');
 if (s1) {
 *s1 = '\0';
 
 It happens in the above line.
 
 Caused by: ash.c:
 
 static void
 tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char
 **argv, char **envp)
 {
 #if ENABLE_FEATURE_SH_STANDALONE
 if (applet_no = 0) {
 if (APPLET_IS_NOEXEC(applet_no)) {
 clearenv();
 while (*envp)
 putenv(*envp++);
 ^^
 run_applet_no_and_exit(applet_no, argv);
 }
 /* re-exec ourselves with the new arguments */
 execve(bb_busybox_exec_path, argv, envp);
 /* If they called chroot or otherwise made the binary no 
 longer
  * executable, fall through */
 }
 #endif
 
 Basically, we putenv() a string which is constant,
 and when we try to modify it, we segfault.

Thank you Denys, thank you very much for figuring it out.

I was about to add printfs here and there, planned to do
that today evening.

 I think Debian's patch does something which is not supported.

Funny you mention it.  The thing is: with the patch,
there's just ONE variable marked as VEXPORT, and no
variable is marked as such without the patch.

So I'm not surprized it doesn't work.

Looking at the other places, everywhere where VEXPORT
flag is used, the variable in question is dynamically
allocated.  So setting this flag for initial value is
indeed not supported -- maybe it is a good idea to
document this fact in the code.

Now, for the root issue -- exporting $PATH from [a]sh --
I inherited this patch together with busybox debian
package, and am now trying to understand where it
comes from and for what.  I'll drop it from the next
Debian release (wheezy+1), since neither bash nor
dash exports $PATH by default.  But for now, I'll
have to change the way stdpath is set up, to allow
VEXPORT to work correctly.

Thank you very much for finding the root of the issue!

/mjt
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: interesting segfault when running awk as pid==1

2012-07-06 Thread Michael Tokarev
On 06.07.2012 04:10, ra...@gmx.de wrote:
 Hi Michael !
 
 I've an interesting case here, when busybox (in debian)
 segfaults when run in initramfs as pid == 1, when invoking
 awk applet (PREFER_APPLETS is set to yes).  I can't trigger
 it with pid != 1, and since pid=1 is special in linux,
 I can't really debug it too.
 
 I hit this problem some years ago. May be same reason. Try running awk
 via env command and setup some environment variables. pid 1 is special
 as environment on invocation may be empty (or something missing, most
 likely SHELL or PATH).

As I stated in my initial email, when running awk from a subshell
it works.  I know PID=1 is special, and for one, it can't be straced
or debugged.  PATH isn't empty since busybox ash sets it to some
value, but PATH at least _should_ be irrelevant, since awk is NOEXEC
applet.  And finally, it isn't a solution to run it from a subshell,
since running awk from within /init in initramfs is a valid usage
case.

Thanks for trying,

/mjt
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: interesting segfault when running awk as pid==1

2012-07-06 Thread Laurent Bercot
 As I stated in my initial email, when running awk from a subshell
 it works.  I know PID=1 is special, and for one, it can't be straced
 or debugged.

 Actually, on some Linux versions (I'm not certain which ones though,
but it should work on modern kernels), process 1 *can* be straced:
somehow get a shell running and do strace -p 1. If you're not afraid
of dirty hacks, you could even run that from your /init, if everything
is properly mounted:
 ( strace -p 1 /dev/null /dev/null 2/tmp/strace-file ) 
or even replace /tmp/strace-file with /dev/tty for a live performance.


 And finally, it isn't a solution to run it from a subshell,
 since running awk from within /init in initramfs is a valid usage
 case.

 But are you really running awk as process 1 ?
 I doubt your /init script is *executing* awk. If it was, then after
performing its work, awk would die, and your kernel would panic.
I suspect that instead, your /init script looks like

#!/bin/sh
...
awk something
...
exec chroot foobar /sbin/init

 in which case you are *not* running awk as process 1: your shell is
forking first, then executing awk as a child. The question then becomes,
why is there a problem when awk is run directly as process 1's child.

-- 
 Laurent
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: interesting segfault when running awk as pid==1

2012-07-06 Thread Michael Tokarev
On 06.07.2012 15:03, Laurent Bercot wrote:
 As I stated in my initial email, when running awk from a subshell
 it works.  I know PID=1 is special, and for one, it can't be straced
 or debugged.
 
  Actually, on some Linux versions (I'm not certain which ones though,
 but it should work on modern kernels), process 1 *can* be straced:
 somehow get a shell running and do strace -p 1. If you're not afraid
 of dirty hacks, you could even run that from your /init, if everything
 is properly mounted:
  ( strace -p 1 /dev/null /dev/null 2/tmp/strace-file ) 
 or even replace /tmp/strace-file with /dev/tty for a live performance.

I tried this right away, but failed: strace does not show anything
at all in that case, even if the process 1 actually does something.

No, I'm not afraid at all, since it is trivial to experiment in
a virtual machine.

And I don't think strace will do anything interesting here: I
looked at what happens when busybox ash spawns awk in a regular
case, there, it just forks (with a pipe open) and does one or
two read/writes -- it is ofcourse not enough information to
understand what's going on.  It may help a bit ofcourse, if
I'll add a few debug printfs here and there.

Ideally it'd be nice to get a coredump, but for some reason
the process being fork'ed in this context isn't dumpable.

 And finally, it isn't a solution to run it from a subshell,
 since running awk from within /init in initramfs is a valid usage
 case.
 
  But are you really running awk as process 1 ?
  I doubt your /init script is *executing* awk. If it was, then after
 performing its work, awk would die, and your kernel would panic.
 I suspect that instead, your /init script looks like
 
 #!/bin/sh
 ...
 awk something
 ...
 exec chroot foobar /sbin/init
 
  in which case you are *not* running awk as process 1: your shell is
 forking first, then executing awk as a child. The question then becomes,
 why is there a problem when awk is run directly as process 1's child.

Well.  My $subject is inaccurate.  I meant to say when awk is
spawned from pid=1 as NOEXEC applet.  The code like

  rootfs=`awk '$2==/{print $1}`

or anything of this theme.  This works:

  rootfs=`/bin/awk '$2==/{print $1}`
  rootfs=`busybox awk '$2==/{print $1}`

and this

  rootfs=`awk '$2==/{print $1}`

segfaults, just like a bare 'awk' call:

  awk

(in normal case it produces an error message
about invalid usage).


Thank you!

/mjt
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: interesting segfault when running awk as pid==1

2012-07-06 Thread ra...@gmx.de
Hi Michael,

I'm still mentioning to look in detail on the content of the
environment. I know awk itself shell not need PATH etc., but Busybox
does. As Busybox is a multi call binary it contains common code. First
to invoke the applet and second for internal library functions. Some of
those code need environment information or other information possibly
not required by a bare awk.

Running awk from a shell script which is run as /bin/init differs in
environment from running a second shell and invoking awk from there. As
soon as an interactive shell is invoked the shell startup code set
several environment defaults in case there are needed. This may indeed
fix your segfault problem.

I know I had trouble for weeks as I stumbled on this. And came of a so
simple solution ... it was just to invoke awk via env that is:

env - awk AWKARGS

This sometimes solved my segfaulting start problem with awk. In othe
cases I needed to manually set some environment values.

It is good practice to set some environment variables right at the start
of the script running as init:

export TERM=linux
export USER=root
export HOME=/root
export SHELL=/bin/sh
export PATH=/bin:/sbin:/usr/bin:/usr/sbin

This shall give you a sane environment where most commands work as
expected. Without this the contents of the environment is purely
random (system/kernel version depended), as Busybox does not setup
a full initial environment, if invoked as init script (default
behavior of POSIX sh for non interactive invocation).

Harald
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: interesting segfault when running awk as pid==1

2012-07-05 Thread ra...@gmx.de
Hi Michael !

 I've an interesting case here, when busybox (in debian)
 segfaults when run in initramfs as pid == 1, when invoking
 awk applet (PREFER_APPLETS is set to yes).  I can't trigger
 it with pid != 1, and since pid=1 is special in linux,
 I can't really debug it too.

I hit this problem some years ago. May be same reason. Try running awk
via env command and setup some environment variables. pid 1 is special
as environment on invocation may be empty (or something missing, most
likely SHELL or PATH).

Harald
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox