From: Thomas Adam Subject: gotwebd: propagate chroot path to child processes To: Game of Trees Date: Mon, 23 Feb 2026 16:10:41 +0000 Because gotweb's config is read in the parent process, the chroot value is never sent to the children of gotwebd. This effectively means that the chroot value in the config is ignored, and as a consequence, defaults to "/var/www". On some systems, "/var/www" may well exist which is why this bug has been masked but on non-BSD systems, this is not always the case. OK? diff /tmp/got path + /tmp/got commit - dd1ae34cdb71b1414ded065da4834621608a8b3b blob - 2b6247635a38c8300131ee83554434b8d2f50500 file + gotwebd/gotwebd.c --- gotwebd/gotwebd.c +++ gotwebd/gotwebd.c @@ -498,7 +498,7 @@ spawn_process(struct gotwebd *env, const char *argv0, enum gotwebd_proc_type proc_type, const char *username, const char *www_user, void (*handler)(int, short, void *)) { - const char *argv[10]; + const char *argv[12]; int argc = 0; int p[2]; pid_t pid; @@ -557,6 +557,10 @@ spawn_process(struct gotwebd *env, const char *argv0, argv[argc++] = "-G"; argv[argc++] = usernames; } + if (strcmp(env->httpd_chroot, D_HTTPD_CHROOT) != 0) { + argv[argc++] = "-C"; + argv[argc++] = env->httpd_chroot; + } if (strcmp(env->gotwebd_conffile, GOTWEBD_CONF) != 0) { argv[argc++] = "-f"; argv[argc++] = env->gotwebd_conffile; @@ -923,12 +927,18 @@ main(int argc, char **argv) fatal("%s: calloc", __func__); config_init(env); - while ((ch = getopt(argc, argv, "A:D:dG:f:F:L:nS:vW:")) != -1) { + while ((ch = getopt(argc, argv, "A:C:D:dG:f:F:L:nS:vW:")) != -1) { switch (ch) { case 'A': proc_type = GOTWEBD_PROC_AUTH; get_usernames(&gotwebd_username, &www_username, optarg); break; + case 'C': + if (strlcpy(env->httpd_chroot, optarg, + sizeof(env->httpd_chroot)) >= + sizeof(env->httpd_chroot)) + fatalx("chroot path too long"); + break; case 'D': if (cmdline_symset(optarg) < 0) log_warnx("could not parse macro definition %s", @@ -1052,6 +1062,8 @@ main(int argc, char **argv) if (chdir("/") == -1) fatal("chdir /"); + log_info("Using chroot: %s", env->httpd_chroot); + if (setgroups(1, &pw->pw_gid) == -1 || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1 || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)