diff options
author | Omar Polo <op@omarpolo.com> | 2024-06-14 12:42:18 +0000 |
---|---|---|
committer | Omar Polo <op@omarpolo.com> | 2024-06-14 12:42:18 +0000 |
commit | 23ea79cec6c409d3b98977727b8d5ed857acfd4d (patch) | |
tree | 2312cacca075286d6c9e3ac22c02ae246f1f52c7 | |
parent | c616a6d6f4299ab0070afdb23aebe46ff4fb2e6a (diff) |
propagate prefork value
otherwise the child processes still believet the prefork value is
3 and can end up reading/writing out of bounds when setting up the
sockets. Actually, server processes shouldn't create pipes to other
servers, but this is left for a follow-up diff.
Issue reported by la ninpre, thank you!
-rw-r--r-- | gmid.c | 11 | ||||
-rw-r--r-- | proc.c | 13 | ||||
-rwxr-xr-x | regress/regress | 1 | ||||
-rw-r--r-- | regress/tests.sh | 7 |
4 files changed, 29 insertions, 3 deletions
@@ -54,7 +54,7 @@ static struct privsep_proc procs[] = { { "logger", PROC_LOGGER, main_dispatch_logger, logger }, }; -static const char *opts = "c:D:fI:hnP:T:U:VvX:"; +static const char *opts = "c:D:fI:J:hnP:T:U:VvX:"; static const struct option longopts[] = { {"help", no_argument, NULL, 'h'}, @@ -240,6 +240,7 @@ main(int argc, char **argv) int ch, conftest = 0; int proc_instance = 0; int proc_id = PROC_PARENT; + int nprocs = 0; int argc0 = argc; setlocale(LC_CTYPE, ""); @@ -269,6 +270,13 @@ main(int argc, char **argv) if (errstr != NULL) fatalx("invalid process instance"); break; + case 'J': + nprocs = strtonum(optarg, 0, PROC_MAX_INSTANCES, + &errstr); + if (errstr != NULL) + fatalx("invalid process instance"); + log_warnx("nprocs is %d", nprocs); + break; case 'n': conftest++; break; @@ -320,6 +328,7 @@ main(int argc, char **argv) if (chroot && strlcpy(conf->chroot, chroot, sizeof(conf->chroot)) >= sizeof(conf->chroot)) fatalx("chroot path too long: %s", chroot); + conf->prefork = nprocs; } if ((ps = calloc(1, sizeof(*ps))) == NULL) @@ -79,14 +79,17 @@ proc_exec(struct privsep *ps, struct privsep_proc *procs, unsigned int nproc, unsigned int proc, nargc, i, proc_i, proc_X = 0; const char **nargv; struct privsep_proc *p; - char num[32]; + char num[32], prefork[32]; int fd; /* Prepare the new process argv. */ - nargv = calloc(argc + 9, sizeof(char *)); + nargv = calloc(argc + 11, sizeof(char *)); if (nargv == NULL) fatal("%s: calloc", __func__); + /* Update prefork number */ + snprintf(prefork, sizeof(prefork), "%d", ps->ps_instances[PROC_SERVER]); + /* Copy call argument first. */ nargc = 0; nargv[nargc++] = argv[0]; @@ -106,6 +109,10 @@ proc_exec(struct privsep *ps, struct privsep_proc *procs, unsigned int nproc, nargc++; } + /* Set server prefork number */ + nargv[nargc++] = "-J"; + nargv[nargc++] = prefork; + /* Point process instance arg to stack and copy the original args. */ nargv[nargc++] = "-I"; nargv[nargc++] = num; @@ -354,6 +361,8 @@ proc_setup(struct privsep *ps, struct privsep_proc *procs, unsigned int nproc) */ for (src = 0; src < PROC_MAX; src++) { /* Allocate destination array for each process */ + log_debug("allocating %d for proc %d/%d", + ps->ps_instances[src], src, PROC_MAX); if ((ps->ps_pipes[src] = calloc(ps->ps_instances[src], sizeof(struct privsep_pipes))) == NULL) fatal("%s: calloc", __func__); diff --git a/regress/regress b/regress/regress index 0ace045..82d17a9 100755 --- a/regress/regress +++ b/regress/regress @@ -68,6 +68,7 @@ run_test test_log_file run_test test_ipv4_addr run_test test_ipv6_addr need_ipv6 run_test test_ipv6_server need_ipv6 +run_test test_high_prefork # TODO: add test that uses only a TLSv1.2 or TLSv1.3 # TODO: add a test that attempt to serve a non-regular file diff --git a/regress/tests.sh b/regress/tests.sh index 4581df0..7648278 100644 --- a/regress/tests.sh +++ b/regress/tests.sh @@ -521,3 +521,10 @@ test_ipv6_server() { fetch / check_reply "20 text/gemini" "# hello world" || return 1 } + +test_high_prefork() { + setup_simple_test 'prefork 12' + + fetch / + check_reply "20 text/gemini" "# hello world" || return 1 +} |