Commit Diff


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);