unix-spawn.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2020 Andy Green <[email protected]>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to
  8. * deal in the Software without restriction, including without limitation the
  9. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. * sell copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. * IN THE SOFTWARE.
  23. */
  24. #if !defined(_GNU_SOURCE)
  25. #define _GNU_SOURCE
  26. #endif
  27. #include "private-lib-core.h"
  28. #include <unistd.h>
  29. void
  30. lws_spawn_timeout(struct lws_sorted_usec_list *sul)
  31. {
  32. struct lws_spawn_piped *lsp = lws_container_of(sul,
  33. struct lws_spawn_piped, sul);
  34. lwsl_warn("%s: spawn exceeded timeout, killing\n", __func__);
  35. lws_spawn_piped_kill_child_process(lsp);
  36. }
  37. void
  38. lws_spawn_sul_reap(struct lws_sorted_usec_list *sul)
  39. {
  40. struct lws_spawn_piped *lsp = lws_container_of(sul,
  41. struct lws_spawn_piped, sul_reap);
  42. lwsl_notice("%s: reaping spawn after last stdpipe, tries left %d\n",
  43. __func__, lsp->reap_retry_budget);
  44. if (!lws_spawn_reap(lsp) && !lsp->pipes_alive) {
  45. if (--lsp->reap_retry_budget) {
  46. lws_sul_schedule(lsp->info.vh->context, lsp->info.tsi,
  47. &lsp->sul_reap, lws_spawn_sul_reap,
  48. 250 * LWS_US_PER_MS);
  49. } else {
  50. lwsl_err("%s: Unable to reap lsp %p, killing\n",
  51. __func__, lsp);
  52. lsp->reap_retry_budget = 20;
  53. lws_spawn_piped_kill_child_process(lsp);
  54. }
  55. }
  56. }
  57. static struct lws *
  58. lws_create_basic_wsi(struct lws_context *context, int tsi,
  59. const struct lws_role_ops *ops)
  60. {
  61. size_t s = sizeof(struct lws);
  62. struct lws *new_wsi;
  63. if (!context->vhost_list)
  64. return NULL;
  65. if ((unsigned int)context->pt[tsi].fds_count ==
  66. context->fd_limit_per_thread - 1) {
  67. lwsl_err("no space for new conn\n");
  68. return NULL;
  69. }
  70. #if defined(LWS_WITH_EVENT_LIBS)
  71. s += context->event_loop_ops->evlib_size_wsi;
  72. #endif
  73. new_wsi = lws_zalloc(s, "new wsi");
  74. if (new_wsi == NULL) {
  75. lwsl_err("Out of memory for new connection\n");
  76. return NULL;
  77. }
  78. #if defined(LWS_WITH_EVENT_LIBS)
  79. new_wsi->evlib_wsi = (uint8_t *)new_wsi + sizeof(*new_wsi);
  80. #endif
  81. new_wsi->tsi = tsi;
  82. new_wsi->a.context = context;
  83. new_wsi->pending_timeout = NO_PENDING_TIMEOUT;
  84. new_wsi->rxflow_change_to = LWS_RXFLOW_ALLOW;
  85. /* initialize the instance struct */
  86. lws_role_transition(new_wsi, 0, LRS_ESTABLISHED, ops);
  87. new_wsi->hdr_parsing_completed = 0;
  88. new_wsi->position_in_fds_table = LWS_NO_FDS_POS;
  89. /*
  90. * these can only be set once the protocol is known
  91. * we set an unestablished connection's protocol pointer
  92. * to the start of the defauly vhost supported list, so it can look
  93. * for matching ones during the handshake
  94. */
  95. new_wsi->user_space = NULL;
  96. new_wsi->desc.sockfd = LWS_SOCK_INVALID;
  97. context->count_wsi_allocated++;
  98. return new_wsi;
  99. }
  100. void
  101. lws_spawn_piped_destroy(struct lws_spawn_piped **_lsp)
  102. {
  103. struct lws_spawn_piped *lsp = *_lsp;
  104. int n;
  105. if (!lsp)
  106. return;
  107. lws_dll2_remove(&lsp->dll);
  108. lws_sul_cancel(&lsp->sul);
  109. lws_sul_cancel(&lsp->sul_reap);
  110. for (n = 0; n < 3; n++) {
  111. #if 0
  112. if (lsp->pipe_fds[n][!!(n == 0)] == 0)
  113. lwsl_err("ZERO FD IN CGI CLOSE");
  114. if (lsp->pipe_fds[n][!!(n == 0)] >= 0) {
  115. close(lsp->pipe_fds[n][!!(n == 0)]);
  116. lsp->pipe_fds[n][!!(n == 0)] = LWS_SOCK_INVALID;
  117. }
  118. #endif
  119. if (lsp->stdwsi[n]) {
  120. lws_set_timeout(lsp->stdwsi[n], 1, LWS_TO_KILL_ASYNC);
  121. lsp->stdwsi[n] = NULL;
  122. }
  123. }
  124. lws_free_set_NULL((*_lsp));
  125. }
  126. int
  127. lws_spawn_reap(struct lws_spawn_piped *lsp)
  128. {
  129. long hz = sysconf(_SC_CLK_TCK); /* accounting Hz */
  130. void *opaque = lsp->info.opaque;
  131. lsp_cb_t cb = lsp->info.reap_cb;
  132. struct lws_spawn_piped temp;
  133. struct tms tms;
  134. int n;
  135. if (lsp->child_pid < 1)
  136. return 0;
  137. /* check if exited, do not reap yet */
  138. memset(&lsp->si, 0, sizeof(lsp->si));
  139. n = waitid(P_PID, lsp->child_pid, &lsp->si, WEXITED | WNOHANG | WNOWAIT);
  140. if (n < 0) {
  141. lwsl_info("%s: child %d still running\n", __func__, lsp->child_pid);
  142. return 0;
  143. }
  144. if (!lsp->si.si_code)
  145. return 0;
  146. /* his process has exited... */
  147. if (!lsp->reaped) {
  148. /* mark the earliest time we knew he had gone */
  149. lsp->reaped = lws_now_usecs();
  150. /*
  151. * Switch the timeout to restrict the amount of grace time
  152. * to drain stdwsi
  153. */
  154. lws_sul_schedule(lsp->info.vh->context, lsp->info.tsi,
  155. &lsp->sul, lws_spawn_timeout,
  156. 5 * LWS_US_PER_SEC);
  157. }
  158. /*
  159. * Stage finalizing our reaction to the process going down until the
  160. * stdwsi flushed whatever is in flight and all noticed they were
  161. * closed. For that reason, each stdwsi close must call lws_spawn_reap
  162. * to check if that was the last one and we can proceed with the reap.
  163. */
  164. if (!lsp->ungraceful && lsp->pipes_alive) {
  165. lwsl_info("%s: %d stdwsi alive, not reaping\n", __func__,
  166. lsp->pipes_alive);
  167. return 0;
  168. }
  169. /* we reached the reap point, no need for timeout wait */
  170. lws_sul_cancel(&lsp->sul);
  171. /*
  172. * All the stdwsi went down, nothing more is coming... it's over
  173. * Collect the final information and then reap the dead process
  174. */
  175. if (times(&tms) != (clock_t) -1) {
  176. /*
  177. * Cpu accounting in us
  178. */
  179. lsp->accounting[0] = ((uint64_t)tms.tms_cstime * 1000000) / hz;
  180. lsp->accounting[1] = ((uint64_t)tms.tms_cutime * 1000000) / hz;
  181. lsp->accounting[2] = ((uint64_t)tms.tms_stime * 1000000) / hz;
  182. lsp->accounting[3] = ((uint64_t)tms.tms_utime * 1000000) / hz;
  183. }
  184. temp = *lsp;
  185. n = waitid(P_PID, lsp->child_pid, &temp.si, WEXITED | WNOHANG);
  186. temp.si.si_status &= 0xff; /* we use b8 + for flags */
  187. lwsl_info("%s: waitd says %d, process exit %d\n",
  188. __func__, n, temp.si.si_status);
  189. lsp->child_pid = -1;
  190. /* destroy the lsp itself first (it's freed and plsp set NULL */
  191. if (lsp->info.plsp)
  192. lws_spawn_piped_destroy(lsp->info.plsp);
  193. /* then do the parent callback informing it's destroyed */
  194. if (cb)
  195. cb(opaque, temp.accounting, &temp.si,
  196. temp.we_killed_him_timeout |
  197. (temp.we_killed_him_spew << 1));
  198. return 1; /* was reaped */
  199. }
  200. int
  201. lws_spawn_piped_kill_child_process(struct lws_spawn_piped *lsp)
  202. {
  203. int status, n;
  204. if (lsp->child_pid <= 0)
  205. return 1;
  206. lsp->ungraceful = 1; /* don't wait for flushing, just kill it */
  207. if (lws_spawn_reap(lsp))
  208. /* that may have invalidated lsp */
  209. return 0;
  210. /* kill the process group */
  211. n = kill(-lsp->child_pid, SIGTERM);
  212. lwsl_debug("%s: SIGTERM child PID %d says %d (errno %d)\n", __func__,
  213. lsp->child_pid, n, errno);
  214. if (n < 0) {
  215. /*
  216. * hum seen errno=3 when process is listed in ps,
  217. * it seems we don't always retain process grouping
  218. *
  219. * Direct these fallback attempt to the exact child
  220. */
  221. n = kill(lsp->child_pid, SIGTERM);
  222. if (n < 0) {
  223. n = kill(lsp->child_pid, SIGPIPE);
  224. if (n < 0) {
  225. n = kill(lsp->child_pid, SIGKILL);
  226. if (n < 0)
  227. lwsl_info("%s: SIGKILL PID %d "
  228. "failed errno %d "
  229. "(maybe zombie)\n", __func__,
  230. lsp->child_pid, errno);
  231. }
  232. }
  233. }
  234. /* He could be unkillable because he's a zombie */
  235. n = 1;
  236. while (n > 0) {
  237. n = waitpid(-lsp->child_pid, &status, WNOHANG);
  238. if (n > 0)
  239. lwsl_debug("%s: reaped PID %d\n", __func__, n);
  240. if (n <= 0) {
  241. n = waitpid(lsp->child_pid, &status, WNOHANG);
  242. if (n > 0)
  243. lwsl_debug("%s: reaped PID %d\n", __func__, n);
  244. }
  245. }
  246. lws_spawn_reap(lsp);
  247. /* that may have invalidated lsp */
  248. return 0;
  249. }
  250. /*
  251. * Deals with spawning a subprocess and executing it securely with stdin/out/err
  252. * diverted into pipes
  253. */
  254. struct lws_spawn_piped *
  255. lws_spawn_piped(const struct lws_spawn_piped_info *i)
  256. {
  257. const struct lws_protocols *pcol = i->vh->context->vhost_list->protocols;
  258. struct lws_context *context = i->vh->context;
  259. struct lws_spawn_piped *lsp;
  260. const char *wd;
  261. int n, m;
  262. if (i->protocol_name)
  263. pcol = lws_vhost_name_to_protocol(i->vh, i->protocol_name);
  264. if (!pcol) {
  265. lwsl_err("%s: unknown protocol %s\n", __func__,
  266. i->protocol_name ? i->protocol_name : "default");
  267. return NULL;
  268. }
  269. lsp = lws_zalloc(sizeof(*lsp), __func__);
  270. if (!lsp)
  271. return NULL;
  272. /* wholesale take a copy of info */
  273. lsp->info = *i;
  274. lsp->reap_retry_budget = 20;
  275. /*
  276. * Prepare the stdin / out / err pipes
  277. */
  278. for (n = 0; n < 3; n++) {
  279. lsp->pipe_fds[n][0] = -1;
  280. lsp->pipe_fds[n][1] = -1;
  281. }
  282. /* create pipes for [stdin|stdout] and [stderr] */
  283. for (n = 0; n < 3; n++) {
  284. if (pipe(lsp->pipe_fds[n]) == -1)
  285. goto bail1;
  286. lws_plat_apply_FD_CLOEXEC(lsp->pipe_fds[n][n == 0]);
  287. }
  288. /*
  289. * At this point, we have 6 pipe fds open on lws side and no wsis
  290. * bound to them
  291. */
  292. /* create wsis for each stdin/out/err fd */
  293. for (n = 0; n < 3; n++) {
  294. lsp->stdwsi[n] = lws_create_basic_wsi(i->vh->context, i->tsi,
  295. i->ops ? i->ops : &role_ops_raw_file);
  296. if (!lsp->stdwsi[n]) {
  297. lwsl_err("%s: unable to create lsp stdwsi\n", __func__);
  298. goto bail2;
  299. }
  300. lsp->stdwsi[n]->lsp_channel = n;
  301. lws_vhost_bind_wsi(i->vh, lsp->stdwsi[n]);
  302. lsp->stdwsi[n]->a.protocol = pcol;
  303. lsp->stdwsi[n]->a.opaque_user_data = i->opaque;
  304. lwsl_debug("%s: lsp stdwsi %p: pipe idx %d -> fd %d / %d\n", __func__,
  305. lsp->stdwsi[n], n, lsp->pipe_fds[n][n == 0],
  306. lsp->pipe_fds[n][n != 0]);
  307. /* read side is 0, stdin we want the write side, others read */
  308. lsp->stdwsi[n]->desc.sockfd = lsp->pipe_fds[n][n == 0];
  309. if (fcntl(lsp->pipe_fds[n][n == 0], F_SETFL, O_NONBLOCK) < 0) {
  310. lwsl_err("%s: setting NONBLOCK failed\n", __func__);
  311. goto bail2;
  312. }
  313. /*
  314. * We have bound 3 x pipe fds to wsis, wr side of stdin and rd
  315. * side of stdout / stderr... those are marked CLOEXEC so they
  316. * won't go through the fork
  317. *
  318. * rd side of stdin and wr side of stdout / stderr are open but
  319. * not bound to anything on lws side.
  320. */
  321. }
  322. /*
  323. * Stitch the wsi fd into the poll wait
  324. */
  325. for (n = 0; n < 3; n++) {
  326. if (context->event_loop_ops->sock_accept)
  327. if (context->event_loop_ops->sock_accept(lsp->stdwsi[n]))
  328. goto bail3;
  329. if (__insert_wsi_socket_into_fds(context, lsp->stdwsi[n]))
  330. goto bail3;
  331. if (i->opt_parent) {
  332. lsp->stdwsi[n]->parent = i->opt_parent;
  333. lsp->stdwsi[n]->sibling_list = i->opt_parent->child_list;
  334. i->opt_parent->child_list = lsp->stdwsi[n];
  335. }
  336. }
  337. if (lws_change_pollfd(lsp->stdwsi[LWS_STDIN], LWS_POLLIN, LWS_POLLOUT))
  338. goto bail3;
  339. if (lws_change_pollfd(lsp->stdwsi[LWS_STDOUT], LWS_POLLOUT, LWS_POLLIN))
  340. goto bail3;
  341. if (lws_change_pollfd(lsp->stdwsi[LWS_STDERR], LWS_POLLOUT, LWS_POLLIN))
  342. goto bail3;
  343. lwsl_info("%s: fds in %d, out %d, err %d\n", __func__,
  344. lsp->stdwsi[LWS_STDIN]->desc.sockfd,
  345. lsp->stdwsi[LWS_STDOUT]->desc.sockfd,
  346. lsp->stdwsi[LWS_STDERR]->desc.sockfd);
  347. /* we are ready with the redirection pipes... do the (v)fork */
  348. #if !defined(LWS_HAVE_VFORK) || !defined(LWS_HAVE_EXECVPE)
  349. lsp->child_pid = fork();
  350. #else
  351. lsp->child_pid = vfork();
  352. #endif
  353. if (lsp->child_pid < 0) {
  354. lwsl_err("%s: fork failed, errno %d", __func__, errno);
  355. goto bail3;
  356. }
  357. #if defined(__linux__)
  358. if (!lsp->child_pid)
  359. prctl(PR_SET_PDEATHSIG, SIGTERM);
  360. #endif
  361. if (lsp->info.disable_ctrlc)
  362. /* stops non-daemonized main processess getting SIGINT
  363. * from TTY */
  364. #if defined(__FreeBSD__)
  365. setpgid(0, 0);
  366. #else
  367. setpgrp();
  368. #endif
  369. if (lsp->child_pid) {
  370. /*
  371. * We are the parent process. We can close our copy of the
  372. * "other" side of the pipe fds, ie, rd for stdin and wr for
  373. * stdout / stderr.
  374. */
  375. for (n = 0; n < 3; n++)
  376. /* these guys didn't have any wsi footprint */
  377. close(lsp->pipe_fds[n][n != 0]);
  378. lsp->pipes_alive = 3;
  379. lsp->created = lws_now_usecs();
  380. lwsl_info("%s: lsp %p spawned PID %d\n", __func__, lsp,
  381. lsp->child_pid);
  382. lws_sul_schedule(context, i->tsi, &lsp->sul, lws_spawn_timeout,
  383. i->timeout_us ? i->timeout_us :
  384. 300 * LWS_US_PER_SEC);
  385. if (i->owner)
  386. lws_dll2_add_head(&lsp->dll, i->owner);
  387. if (i->timeout_us)
  388. lws_sul_schedule(context, i->tsi, &lsp->sul,
  389. lws_spawn_timeout, i->timeout_us);
  390. return lsp;
  391. }
  392. /*
  393. * We are the forked process, redirect and kill inherited things.
  394. *
  395. * Because of vfork(), we cannot do anything that changes pages in
  396. * the parent environment. Stuff that changes kernel state for the
  397. * process is OK. Stuff that happens after the execvpe() is OK.
  398. */
  399. if (i->chroot_path && chroot(i->chroot_path)) {
  400. lwsl_err("%s: child chroot %s failed, errno %d\n",
  401. __func__, i->chroot_path, errno);
  402. exit(2);
  403. }
  404. /* cwd: somewhere we can at least read things and enter it */
  405. wd = i->wd;
  406. if (!wd)
  407. wd = "/tmp";
  408. if (chdir(wd))
  409. lwsl_notice("%s: Failed to cd to %s\n", __func__, wd);
  410. /*
  411. * Bind the child's stdin / out / err to its side of our pipes
  412. */
  413. for (m = 0; m < 3; m++) {
  414. if (dup2(lsp->pipe_fds[m][m != 0], m) < 0) {
  415. lwsl_err("%s: stdin dup2 failed\n", __func__);
  416. goto bail3;
  417. }
  418. /*
  419. * CLOEXEC on the lws-side of the pipe fds should have already
  420. * dealt with closing those for the child perspective.
  421. *
  422. * Now it has done the dup, the child should close its original
  423. * copies of its side of the pipes.
  424. */
  425. close(lsp->pipe_fds[m][m != 0]);
  426. }
  427. #if !defined(LWS_HAVE_VFORK) || !defined(LWS_HAVE_EXECVPE)
  428. #if defined(__linux__) || defined(__APPLE__)
  429. m = 0;
  430. while (i->env_array[m]){
  431. char *p = strchr(i->env_array[m], '=');
  432. *p++ = '\0';
  433. setenv(i->env_array[m], p, 1);
  434. m++;
  435. }
  436. #endif
  437. execvp(i->exec_array[0], (char * const *)&i->exec_array[0]);
  438. #else
  439. execvpe(i->exec_array[0], (char * const *)&i->exec_array[0],
  440. &i->env_array[0]);
  441. #endif
  442. lwsl_err("%s: child exec of %s failed %d\n", __func__, i->exec_array[0],
  443. LWS_ERRNO);
  444. _exit(1);
  445. bail3:
  446. while (--n >= 0)
  447. __remove_wsi_socket_from_fds(lsp->stdwsi[n]);
  448. bail2:
  449. for (n = 0; n < 3; n++)
  450. if (lsp->stdwsi[n])
  451. __lws_free_wsi(lsp->stdwsi[n]);
  452. bail1:
  453. for (n = 0; n < 3; n++) {
  454. if (lsp->pipe_fds[n][0] >= 0)
  455. close(lsp->pipe_fds[n][0]);
  456. if (lsp->pipe_fds[n][1] >= 0)
  457. close(lsp->pipe_fds[n][1]);
  458. }
  459. lws_free(lsp);
  460. lwsl_err("%s: failed\n", __func__);
  461. return NULL;
  462. }
  463. void
  464. lws_spawn_stdwsi_closed(struct lws_spawn_piped *lsp, struct lws *wsi)
  465. {
  466. int n;
  467. assert(lsp);
  468. lsp->pipes_alive--;
  469. lwsl_debug("%s: pipes alive %d\n", __func__, lsp->pipes_alive);
  470. if (!lsp->pipes_alive)
  471. lws_sul_schedule(lsp->info.vh->context, lsp->info.tsi,
  472. &lsp->sul_reap, lws_spawn_sul_reap, 1);
  473. for (n = 0; n < 3; n++)
  474. if (lsp->stdwsi[n] == wsi)
  475. lsp->stdwsi[n] = NULL;
  476. }
  477. int
  478. lws_spawn_get_stdfd(struct lws *wsi)
  479. {
  480. return wsi->lsp_channel;
  481. }