Refactor end of service_start() to prevent deref freed svc
An SVC_TYPE_RUN may be deleted by svc_clean_bootstrap() as soon as it's
been collected.  We must not try to dereference that pointer afterwards,
e.g. in svc_is_daemon().
Refactor the whole of it to make the code easier to follow.
@@ -346,22 +346,30 @@ static int service_start(svc_t *svc)
svc->pid = pid;
svc->start_time = jiffies();
-#ifdef INETD_ENABLED
- if (svc_is_inetd_conn(svc) && svc->inetd.type == SOCK_STREAM)
- close(svc->stdin_fd);
-#endif
-
- if (SVC_TYPE_RUN == svc->type) {
+ switch (svc->type) {
+ case SVC_TYPE_RUN:
result = WEXITSTATUS(complete(svc->cmd, pid));
if (!svc_clean_bootstrap(svc)) {
svc->start_time = svc->pid = 0;
svc->once++;
svc_set_state(svc, SVC_STOPPING_STATE);
}
- }
+ break;
- if (svc_is_daemon(svc))
+ case SVC_TYPE_SERVICE:
pid_file_create(svc);
+ break;
+
+#ifdef INETD_ENABLED
+ case SVC_TYPE_INETD_CONN:
+ if (svc->inetd.type == SOCK_STREAM)
+ close(svc->stdin_fd);
+ break;
+#endif
+
+ default:
+ break;
+ }
sigprocmask(SIG_SETMASK, &omask, NULL);
if (do_progress)
