commit 7fed8fa426806e627fcf1e344e4ce134b17a0474 from: Stefan Sperling via: Thomas Adam date: Thu Jun 22 13:10:34 2023 UTC unveil repositories read-only in gotd session process while serving fetches ok op@ commit - e81b604b157f332b391463c0d0b0a114981a5637 commit + 7fed8fa426806e627fcf1e344e4ce134b17a0474 blob - b11c1c1acd745ba6f9cfa1b3e67e1d210de90fe9 blob + 39dce48397cbe1b9b804e1744af2374b52dafeab --- gotd/gotd.c +++ gotd/gotd.c @@ -831,7 +831,8 @@ verify_imsg_src(struct gotd_client *client, struct got return 0; } } - if (proc->type == PROC_SESSION) { + if (proc->type == PROC_SESSION_READ || + proc->type == PROC_SESSION_WRITE) { if (client->session == NULL) { log_warnx("no session found for uid %d", client->euid); return 0; @@ -868,7 +869,8 @@ verify_imsg_src(struct gotd_client *client, struct got ret = 1; break; case GOTD_IMSG_CLIENT_SESSION_READY: - if (proc->type != PROC_SESSION) { + if (proc->type != PROC_SESSION_READ && + proc->type != PROC_SESSION_WRITE) { err = got_error_fmt(GOT_ERR_BAD_PACKET, "unexpected \"ready\" signal from PID %d", proc->pid); @@ -1443,7 +1445,10 @@ start_child(enum gotd_procid proc_id, const char *repo case PROC_AUTH: argv[argc++] = (char *)"-A"; break; - case PROC_SESSION: + case PROC_SESSION_READ: + argv[argc++] = (char *)"-s"; + break; + case PROC_SESSION_WRITE: argv[argc++] = (char *)"-S"; break; case PROC_REPO_READ: @@ -1505,7 +1510,10 @@ start_session_child(struct gotd_client *client, struct if (proc == NULL) return got_error_from_errno("calloc"); - proc->type = PROC_SESSION; + if (client_is_reading(client)) + proc->type = PROC_SESSION_READ; + else + proc->type = PROC_SESSION_WRITE; if (strlcpy(proc->repo_name, repo->name, sizeof(proc->repo_name)) >= sizeof(proc->repo_name)) fatalx("repository name too long: %s", repo->name); @@ -1642,8 +1650,13 @@ start_auth_child(struct gotd_client *client, int requi } static void -apply_unveil_repo_readonly(const char *repo_path) +apply_unveil_repo_readonly(const char *repo_path, int need_tmpdir) { + if (need_tmpdir) { + if (unveil(GOT_TMPDIR_STR, "rwc") == -1) + fatal("unveil %s", GOT_TMPDIR_STR); + } + if (unveil(repo_path, "r") == -1) fatal("unveil %s", repo_path); @@ -1701,7 +1714,7 @@ main(int argc, char **argv) log_init(1, LOG_DAEMON); /* Log to stderr until daemonized. */ - while ((ch = getopt(argc, argv, "Adf:LnP:RSvW")) != -1) { + while ((ch = getopt(argc, argv, "Adf:LnP:RsSvW")) != -1) { switch (ch) { case 'A': proc_id = PROC_AUTH; @@ -1726,8 +1739,11 @@ main(int argc, char **argv) case 'R': proc_id = PROC_REPO_READ; break; + case 's': + proc_id = PROC_SESSION_READ; + break; case 'S': - proc_id = PROC_SESSION; + proc_id = PROC_SESSION_WRITE; break; case 'v': if (verbosity < 3) @@ -1801,7 +1817,7 @@ main(int argc, char **argv) snprintf(title, sizeof(title), "%s %s", gotd_proc_names[proc_id], repo_path); } else if (proc_id == PROC_REPO_READ || proc_id == PROC_REPO_WRITE || - proc_id == PROC_SESSION) { + proc_id == PROC_SESSION_READ || proc_id == PROC_SESSION_WRITE) { error = got_repo_pack_fds_open(&pack_fds); if (error != NULL) fatalx("cannot open pack tempfiles: %s", error->msg); @@ -1865,7 +1881,8 @@ main(int argc, char **argv) auth_main(title, &gotd.repos, repo_path); /* NOTREACHED */ break; - case PROC_SESSION: + case PROC_SESSION_READ: + case PROC_SESSION_WRITE: #ifndef PROFILE /* * The "recvfd" promise is only needed during setup and @@ -1875,9 +1892,12 @@ main(int argc, char **argv) "unveil", NULL) == -1) err(1, "pledge"); #endif - apply_unveil_repo_readwrite(repo_path); + if (proc_id == PROC_SESSION_READ) + apply_unveil_repo_readonly(repo_path, 1); + else + apply_unveil_repo_readwrite(repo_path); session_main(title, repo_path, pack_fds, temp_fds, - &gotd.request_timeout); + &gotd.request_timeout, proc_id); /* NOTREACHED */ break; case PROC_REPO_READ: @@ -1885,7 +1905,7 @@ main(int argc, char **argv) if (pledge("stdio rpath recvfd unveil", NULL) == -1) err(1, "pledge"); #endif - apply_unveil_repo_readonly(repo_path); + apply_unveil_repo_readonly(repo_path, 0); repo_read_main(title, repo_path, pack_fds, temp_fds); /* NOTREACHED */ exit(0); @@ -1894,7 +1914,7 @@ main(int argc, char **argv) if (pledge("stdio rpath recvfd unveil", NULL) == -1) err(1, "pledge"); #endif - apply_unveil_repo_readonly(repo_path); + apply_unveil_repo_readonly(repo_path, 0); repo = gotd_find_repo_by_path(repo_path, &gotd); if (repo == NULL) fatalx("no repository for path %s", repo_path); blob - b08623dd82c94711edc63cc23126b9a581a45c31 blob + 35d6e95f4881eb3c4ce60156fce684fa03070cb4 --- gotd/gotd.h +++ gotd/gotd.h @@ -36,7 +36,8 @@ enum gotd_procid { PROC_GOTD = 0, PROC_LISTEN, PROC_AUTH, - PROC_SESSION, + PROC_SESSION_READ, + PROC_SESSION_WRITE, PROC_REPO_READ, PROC_REPO_WRITE, PROC_MAX, blob - 7a8d4d56a34369a687e7052f5f0279c608065fae blob + 6bb52da0072acc8ca769bbe69c71259b848ccbaf --- gotd/session.c +++ gotd/session.c @@ -59,6 +59,7 @@ static struct gotd_session { int *temp_fds; struct gotd_imsgev parent_iev; struct timeval request_timeout; + enum gotd_procid proc_id; } gotd_session; static struct gotd_session_client { @@ -90,7 +91,7 @@ disconnect(struct gotd_session_client *client) log_debug("uid %d: disconnecting", client->euid); if (gotd_imsg_compose_event(&gotd_session.parent_iev, - GOTD_IMSG_DISCONNECT, PROC_SESSION, -1, NULL, 0) == -1) + GOTD_IMSG_DISCONNECT, gotd_session.proc_id, -1, NULL, 0) == -1) log_warn("imsg compose DISCONNECT"); imsg_clear(&client->repo_child_iev.ibuf); @@ -123,7 +124,7 @@ disconnect_on_error(struct gotd_session_client *client log_warnx("uid %d: %s", client->euid, err->msg); if (err->code != GOT_ERR_EOF) { imsg_init(&ibuf, client->fd); - gotd_imsg_send_error(&ibuf, 0, PROC_SESSION, err); + gotd_imsg_send_error(&ibuf, 0, gotd_session.proc_id, err); imsg_clear(&ibuf); } @@ -249,7 +250,7 @@ send_ref_update_ok(struct gotd_session_client *client, len = sizeof(iok) + iok.name_len; wbuf = imsg_create(&iev->ibuf, GOTD_IMSG_REF_UPDATE_OK, - PROC_SESSION, gotd_session.pid, len); + gotd_session.proc_id, gotd_session.pid, len); if (wbuf == NULL) return got_error_from_errno("imsg_create REF_UPDATE_OK"); @@ -268,7 +269,7 @@ static void send_refs_updated(struct gotd_session_client *client) { if (gotd_imsg_compose_event(&client->iev, GOTD_IMSG_REFS_UPDATED, - PROC_SESSION, -1, NULL, 0) == -1) + gotd_session.proc_id, -1, NULL, 0) == -1) log_warn("imsg compose REFS_UPDATED"); } @@ -294,7 +295,7 @@ send_ref_update_ng(struct gotd_session_client *client, len = sizeof(ing) + ing.name_len + ing.reason_len; wbuf = imsg_create(&iev->ibuf, GOTD_IMSG_REF_UPDATE_NG, - PROC_SESSION, gotd_session.pid, len); + gotd_session.proc_id, gotd_session.pid, len); if (wbuf == NULL) return got_error_from_errno("imsg_create REF_UPDATE_NG"); @@ -777,7 +778,7 @@ forward_want(struct gotd_session_client *client, struc iwant.client_id = client->id; if (gotd_imsg_compose_event(&client->repo_child_iev, GOTD_IMSG_WANT, - PROC_SESSION, -1, &iwant, sizeof(iwant)) == -1) + gotd_session.proc_id, -1, &iwant, sizeof(iwant)) == -1) return got_error_from_errno("imsg compose WANT"); return NULL; @@ -805,7 +806,8 @@ forward_ref_update(struct gotd_session_client *client, iref->client_id = client->id; if (gotd_imsg_compose_event(&client->repo_child_iev, - GOTD_IMSG_REF_UPDATE, PROC_SESSION, -1, iref, datalen) == -1) + GOTD_IMSG_REF_UPDATE, gotd_session.proc_id, -1, + iref, datalen) == -1) err = got_error_from_errno("imsg compose REF_UPDATE"); free(iref); return err; @@ -829,7 +831,7 @@ forward_have(struct gotd_session_client *client, struc ihave.client_id = client->id; if (gotd_imsg_compose_event(&client->repo_child_iev, GOTD_IMSG_HAVE, - PROC_SESSION, -1, &ihave, sizeof(ihave)) == -1) + gotd_session.proc_id, -1, &ihave, sizeof(ihave)) == -1) return got_error_from_errno("imsg compose HAVE"); return NULL; @@ -877,7 +879,7 @@ recv_packfile(struct gotd_session_client *client) /* Send pack pipe end 0 to repo child process. */ if (gotd_imsg_compose_event(&client->repo_child_iev, - GOTD_IMSG_PACKFILE_PIPE, PROC_SESSION, pipe[0], + GOTD_IMSG_PACKFILE_PIPE, gotd_session.proc_id, pipe[0], &ipipe, sizeof(ipipe)) == -1) { err = got_error_from_errno("imsg compose PACKFILE_PIPE"); pipe[0] = -1; @@ -887,7 +889,8 @@ recv_packfile(struct gotd_session_client *client) /* Send pack pipe end 1 to gotsh(1) (expects just an fd, no data). */ if (gotd_imsg_compose_event(&client->iev, - GOTD_IMSG_PACKFILE_PIPE, PROC_SESSION, pipe[1], NULL, 0) == -1) + GOTD_IMSG_PACKFILE_PIPE, gotd_session.proc_id, pipe[1], + NULL, 0) == -1) err = got_error_from_errno("imsg compose PACKFILE_PIPE"); pipe[1] = -1; @@ -925,7 +928,7 @@ recv_packfile(struct gotd_session_client *client) memset(&ifile, 0, sizeof(ifile)); ifile.client_id = client->id; if (gotd_imsg_compose_event(&client->repo_child_iev, - GOTD_IMSG_PACKIDX_FILE, PROC_SESSION, + GOTD_IMSG_PACKIDX_FILE, gotd_session.proc_id, idxfd, &ifile, sizeof(ifile)) == -1) { err = got_error_from_errno("imsg compose PACKIDX_FILE"); idxfd = -1; @@ -939,7 +942,7 @@ recv_packfile(struct gotd_session_client *client) ipack.report_status = 1; if (gotd_imsg_compose_event(&client->repo_child_iev, - GOTD_IMSG_RECV_PACKFILE, PROC_SESSION, packfd, + GOTD_IMSG_RECV_PACKFILE, gotd_session.proc_id, packfd, &ipack, sizeof(ipack)) == -1) { err = got_error_from_errno("imsg compose RECV_PACKFILE"); packfd = -1; @@ -1268,7 +1271,7 @@ list_refs_request(void) return got_error_from_errno("dup"); if (gotd_imsg_compose_event(iev, GOTD_IMSG_LIST_REFS_INTERNAL, - PROC_SESSION, fd, &ilref, sizeof(ilref)) == -1) { + gotd_session.proc_id, fd, &ilref, sizeof(ilref)) == -1) { err = got_error_from_errno("imsg compose LIST_REFS_INTERNAL"); close(fd); return err; @@ -1447,7 +1450,8 @@ done: void session_main(const char *title, const char *repo_path, - int *pack_fds, int *temp_fds, struct timeval *request_timeout) + int *pack_fds, int *temp_fds, struct timeval *request_timeout, + enum gotd_procid proc_id) { const struct got_error *err = NULL; struct event evsigint, evsigterm, evsighup, evsigusr1; @@ -1458,6 +1462,7 @@ session_main(const char *title, const char *repo_path, gotd_session.temp_fds = temp_fds; memcpy(&gotd_session.request_timeout, request_timeout, sizeof(gotd_session.request_timeout)); + gotd_session.proc_id = proc_id; err = got_repo_open(&gotd_session.repo, repo_path, NULL, pack_fds); if (err) @@ -1494,7 +1499,8 @@ session_main(const char *title, const char *repo_path, event_set(&gotd_session.parent_iev.ev, gotd_session.parent_iev.ibuf.fd, EV_READ, session_dispatch, &gotd_session.parent_iev); if (gotd_imsg_compose_event(&gotd_session.parent_iev, - GOTD_IMSG_CLIENT_SESSION_READY, PROC_SESSION, -1, NULL, 0) == -1) { + GOTD_IMSG_CLIENT_SESSION_READY, gotd_session.proc_id, + -1, NULL, 0) == -1) { err = got_error_from_errno("imsg compose CLIENT_SESSION_READY"); goto done; } blob - 671359022739ca8e501ab0fbd98de3e76447490e blob + de20117ce268c646687a1977e8e0c7086a7fb2d6 --- gotd/session.h +++ gotd/session.h @@ -14,4 +14,5 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -void session_main(const char *, const char *, int *, int *, struct timeval *); +void session_main(const char *, const char *, int *, int *, struct timeval *, + enum gotd_procid);