Any logic attempting to guess at the state of startup will give false confidence that the signaling setup is completed.
On 02/15/2018 01:42 PM, Denys Vlasenko wrote: > On Wed, Feb 14, 2018 at 6:53 PM, Deb McLemore <de...@linux.vnet.ibm.com> > wrote: >> The only reproduction we were able to perform injected via a BMC soft >> poweroff being triggered. >> >> This then called into kernel/reboot.c (orderly_poweroff where the >> schedule_work was performed) utilizing the >> >> usermodehelper during the run_cmd /sbin/poweroff. > How about this? > > > +#if ENABLE_FEATURE_WAIT_FOR_INIT > +/* In Linux, "poweroff" may be spawned even before init. > + * For example, with ACPI: > + * linux/drivers/acpi/bus.c: > + * static void sb_notify_work(struct work_struct *dummy) > + * orderly_poweroff(true); > + * linux/kernel/reboot.c: > + * poweroff_cmd[] = "/sbin/poweroff"; > + * static int __orderly_poweroff(bool force) > + * ret = run_cmd(poweroff_cmd); > + * static int run_cmd(const char *cmd) > + * ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); > + * > + * We want to make sure init exists and listens to signals. > + */ > +static int init_was_not_there(void) > +{ > + enum { initial = 5 }; /* 5 seconds should be plenty for timeout */ > + int cnt = initial - 1; > + > + /* Just existence of PID 1 does not mean it installed > + * the handlers already. > + */ > +#if 0 > + while (kill(1, 0) != 0 && --cnt >= 0) > + sleep(1); > +#endif > + /* ... so let's wait for some evidence a usual startup event, > + * mounting of /proc, happened. > + */ > + while (access("/proc/meminfo", F_OK) != 0 && --cnt >= 0) > + sleep(1); > + > + /* Does it look like init wasn't there? */ > + return (cnt != initial - 1); > +} > +#else > +# define init_was_not_there() 0 > +#endif > > int halt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; > int halt_main(int argc UNUSED_PARAM, char **argv) > @@ -171,6 +220,8 @@ int halt_main(int argc UNUSED_PARAM, char **argv) > if (!ENABLE_FEATURE_CALL_TELINIT) { > /* bbox init assumed */ > rc = kill(1, signals[which]); > + if (init_was_not_there()) > + rc = kill(1, signals[which]); > } else { > > > Even if the logic of waiting for "/proc/meminfo" fails > on a weird system which does _not_ mount /proc, > this will not make "poweroff" slow. It will poweroff at once, > then will try to send poweroff signal again a few seconds later > (in all likelihood, way too late in the afterlife). > _______________________________________________ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox