Hi all,
we are using busybox on embedded device which uses debug console only during
development. In this case the kernel
argument `console' is set by uboot to appropriate serial device ttyS0 or
ttyS1. If there is no debug console the uboot
sets the `console=' i.e. null but still on kernel's cmdline.
These days we are wanting to upgrade from busybox 1.2.2 to 1.15.2 but we
observed the following issue. If there is
a debug console everything works fine however if there is no debug console
the '/bin/sh' permanently restarts. See the
log:
*Oct 29 11:23:17 192.168.200.1 init: build-date : 2009-08-28 07:34:38 UTC
Oct 29 11:23:17 192.168.200.1 init: starting pid 524, tty '': '-/bin/sh'
Oct 29 11:23:18 192.168.200.1 init: process '-/bin/sh' (pid 524) exited.
Scheduling for restart.
Oct 29 11:23:18 192.168.200.1 init: starting pid 529, tty '': '-/bin/sh'
Oct 29 11:23:19 192.168.200.1 init: process '-/bin/sh' (pid 529) exited.
Scheduling for restart.
Oct 29 11:23:19 192.168.200.1 init: starting pid 539, tty '': '-/bin/sh'
Oct 29 11:23:20 192.168.200.1 init: process '-/bin/sh' (pid 539) exited.
Scheduling for restart.
Oct 29 11:23:20 192.168.200.1 init: starting pid 546, tty '': '-/bin/sh'
Oct 29 11:23:21 192.168.200.1 init: process '-/bin/sh' (pid 546) exited.
Scheduling for restart.
Oct 29 11:23:21 192.168.200.1 init: starting pid 555, tty '': '-/bin/sh'
Oct 29 11:23:22 192.168.200.1 init: process '-/bin/sh' (pid 555) exited.
Scheduling for restart.
Oct 29 11:23:22 192.168.200.1 init: starting pid 564, tty '': '-/bin/sh'
Oct 29 11:23:23 192.168.200.1 init: process '-/bin/sh' (pid 564) exited.
Scheduling for restart.
Oct 29 11:23:23 192.168.200.1 init: starting pid 571, tty '': '-/bin/sh'
Oct 29 11:23:24 192.168.200.1 init: process '-/bin/sh' (pid 571) exited.
Scheduling for restart.
Oct 29 11:23:24 192.168.200.1 init: starting pid 583, tty '': '-/bin/sh'
Oct 29 11:23:25 192.168.200.1 init: process '-/bin/sh' (pid 583) exited.
Scheduling for restart.
*...
I did a little investigation about this and found that the latest release
which doesn't have this
issue is release 1.4.2. I think the problem is how the stdio is sanitized if
there is not console.
In older releases if the console was missing the CURRENT_VC (current virtual
console)
was finally set as sanitized stdio (correct me if I am wrong) however in the
latter releases
(after 1.4.2) the /dev/null is used which makes `/bin/sh' somehow unhappy
and permanently
exists. If I change the sanitized stdio to CURRENT_VC the problem
disapeares. The patch is
bellow. I wanted to impact the source code as less as possible so I just
have created a new
method *bb_sanitize_stdio_current_vc()*.
Anybody with the same problem and appropriate solution?
Regards,
Ladislav
diff --git a/include/libbb.h
b/include/libbb.h
index 104a399..5963435
100644
---
a/include/libbb.h
+++
b/include/libbb.h
@@ -826,6 +826,7 @@ enum
{
DAEMON_DEVNULL_STDIO =
2,
DAEMON_CLOSE_EXTRA_FDS =
4,
DAEMON_ONLY_SANITIZE = 8, /* internal use
*/
+ DAEMON_CURRENT_VC_STDIO = 16, /* internal use
*/
};
#if
BB_MMU
pid_t fork_or_rexec(void) FAST_FUNC;
@@ -846,6 +847,7 @@ enum {
#endif
void bb_daemonize_or_rexec(int flags, char **argv) FAST_FUNC;
void bb_sanitize_stdio(void) FAST_FUNC;
+void bb_sanitize_stdio_current_vc(void) FAST_FUNC;
/* Clear dangerous stuff, set PATH. Return 1 if was run by different user.
*/
int sanitize_env_if_suid(void) FAST_FUNC;
diff --git a/init/init.c b/init/init.c
index d19839b..f09dfc9 100644
--- a/init/init.c
+++ b/init/init.c
@@ -181,7 +181,7 @@ static void console_init(void)
} else {
/* Make sure fd 0,1,2 are not closed
* (so that they won't be used by future opens) */
- bb_sanitize_stdio();
+ bb_sanitize_stdio_current_vc();
// Users report problems
// /* Make sure init can't be blocked by writing to stderr */
// fcntl(STDERR_FILENO, F_SETFL, fcntl(STDERR_FILENO, F_GETFL)
| O_NONBLOCK);
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index 72edfc7..3d18e42 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -294,12 +294,17 @@ void FAST_FUNC bb_daemonize_or_rexec(int flags, char
**argv)
close(2);
}
+ if (flags & DAEMON_CURRENT_VC_STDIO)
+ fd = open(CURRENT_VC, O_RDWR);
+ else
fd = open(bb_dev_null, O_RDWR);
+
if (fd < 0) {
/* NB: we can be called as bb_sanitize_stdio() from init
* or mdev, and there /dev/null may legitimately not (yet)
exist!
* Do not use xopen above, but obtain _ANY_ open descriptor,
* even bogus one as below. */
+
fd = xopen("/", O_RDONLY); /* don't believe this can fail */
}
@@ -327,3 +332,8 @@ void FAST_FUNC bb_sanitize_stdio(void)
{
bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE, NULL);
}
+
+void FAST_FUNC bb_sanitize_stdio_current_vc(void)
+{
+ bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE +
DAEMON_CURRENT_VC_STDIO, NULL);
+}
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox