aboutsummaryrefslogtreecommitdiff
path: root/init
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2014-11-21 20:10:57 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2014-11-21 20:10:57 +0100
commit2bba9ad67a917de2624d427c8c107ce3e2d3d085 (patch)
tree9557d8e5b55ed51cee72561c53bb712e23785511 /init
parent4e314faa0aecb66717418e9a47a4451aec59262b (diff)
downloadbusybox-w32-2bba9ad67a917de2624d427c8c107ce3e2d3d085.tar.gz
busybox-w32-2bba9ad67a917de2624d427c8c107ce3e2d3d085.tar.bz2
busybox-w32-2bba9ad67a917de2624d427c8c107ce3e2d3d085.zip
init: do not run shutdown/reexec actions from signal handler
this is racy wrt various libc functions such as syslog() function old new delta check_delayed_sigs 182 352 +170 init_main 772 728 -44 restart_handler 74 - -74 halt_reboot_pwoff 79 - -79 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 1/1 up/down: 170/-197) Total: -27 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'init')
-rw-r--r--init/init.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/init/init.c b/init/init.c
index de438be20..d99d68ce4 100644
--- a/init/init.c
+++ b/init/init.c
@@ -822,7 +822,7 @@ static void halt_reboot_pwoff(int sig)
822 822
823/* Handler for QUIT - exec "restart" action, 823/* Handler for QUIT - exec "restart" action,
824 * else (no such action defined) do nothing */ 824 * else (no such action defined) do nothing */
825static void restart_handler(int sig UNUSED_PARAM) 825static void exec_restart_action(void)
826{ 826{
827 struct init_action *a; 827 struct init_action *a;
828 828
@@ -975,6 +975,20 @@ static int check_delayed_sigs(void)
975#endif 975#endif
976 if (sig == SIGINT) 976 if (sig == SIGINT)
977 run_actions(CTRLALTDEL); 977 run_actions(CTRLALTDEL);
978 if (sig == SIGQUIT) {
979 exec_restart_action();
980 /* returns only if no restart action defined */
981 }
982 if ((1 << sig) & (0
983#ifdef SIGPWR
984 + (1 << SIGPWR)
985#endif
986 + (1 << SIGUSR1)
987 + (1 << SIGUSR2)
988 + (1 << SIGTERM)
989 )) {
990 halt_reboot_pwoff(sig);
991 }
978 } 992 }
979} 993}
980 994
@@ -1070,7 +1084,7 @@ int init_main(int argc UNUSED_PARAM, char **argv)
1070 1084
1071#if 0 1085#if 0
1072/* It's 2013, does anyone really still depend on this? */ 1086/* It's 2013, does anyone really still depend on this? */
1073/* If you do, consider adding swapon to sysinot actions then! */ 1087/* If you do, consider adding swapon to sysinit actions then! */
1074/* struct sysinfo is linux-specific */ 1088/* struct sysinfo is linux-specific */
1075# ifdef __linux__ 1089# ifdef __linux__
1076 /* Make sure there is enough memory to do something useful. */ 1090 /* Make sure there is enough memory to do something useful. */
@@ -1134,16 +1148,6 @@ int init_main(int argc UNUSED_PARAM, char **argv)
1134 if (!DEBUG_INIT) { 1148 if (!DEBUG_INIT) {
1135 struct sigaction sa; 1149 struct sigaction sa;
1136 1150
1137 bb_signals(0
1138#ifdef SIGPWR
1139 + (1 << SIGPWR) /* halt */
1140#endif
1141 + (1 << SIGUSR1) /* halt */
1142 + (1 << SIGTERM) /* reboot */
1143 + (1 << SIGUSR2) /* poweroff */
1144 , halt_reboot_pwoff);
1145 signal(SIGQUIT, restart_handler); /* re-exec another init */
1146
1147 /* Stop handler must allow only SIGCONT inside itself */ 1151 /* Stop handler must allow only SIGCONT inside itself */
1148 memset(&sa, 0, sizeof(sa)); 1152 memset(&sa, 0, sizeof(sa));
1149 sigfillset(&sa.sa_mask); 1153 sigfillset(&sa.sa_mask);
@@ -1158,18 +1162,24 @@ int init_main(int argc UNUSED_PARAM, char **argv)
1158 */ 1162 */
1159 sigaction_set(SIGSTOP, &sa); /* pause */ 1163 sigaction_set(SIGSTOP, &sa); /* pause */
1160 1164
1161 /* SIGINT (Ctrl-Alt-Del) must interrupt wait(), 1165 /* These signals must interrupt wait(),
1162 * setting handler without SA_RESTART flag. 1166 * setting handler without SA_RESTART flag.
1163 */ 1167 */
1164 bb_signals_recursive_norestart((1 << SIGINT), record_signo); 1168 bb_signals_recursive_norestart(0
1169 + (1 << SIGINT) /* Ctrl-Alt-Del */
1170 + (1 << SIGQUIT) /* re-exec another init */
1171#ifdef SIGPWR
1172 + (1 << SIGPWR) /* halt */
1173#endif
1174 + (1 << SIGUSR1) /* halt */
1175 + (1 << SIGTERM) /* reboot */
1176 + (1 << SIGUSR2) /* poweroff */
1177#if ENABLE_FEATURE_USE_INITTAB
1178 + (1 << SIGHUP) /* reread /etc/inittab */
1179#endif
1180 , record_signo);
1165 } 1181 }
1166 1182
1167 /* Set up "reread /etc/inittab" handler.
1168 * Handler is set up without SA_RESTART, it will interrupt syscalls.
1169 */
1170 if (!DEBUG_INIT && ENABLE_FEATURE_USE_INITTAB)
1171 bb_signals_recursive_norestart((1 << SIGHUP), record_signo);
1172
1173 /* Now run everything that needs to be run */ 1183 /* Now run everything that needs to be run */
1174 /* First run the sysinit command */ 1184 /* First run the sysinit command */
1175 run_actions(SYSINIT); 1185 run_actions(SYSINIT);