"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: gotsysd: use PATH_MAX for realpath
To:
Martijn van Duren <openbsd+got@list.imperialat.at>, "gameoftrees@openbsd.org" <gameoftrees@openbsd.org>
Date:
Sun, 11 Oct 2026 10:16:28 +0200

Download raw body.

Thread
On Sun, Oct 11, 2026 at 09:15:12AM +0200, Stefan Sperling wrote:
> For realpath(3) specifically we can work around this problem by passing
> NULL for the output buffer, forcing dynamic allocation of the buffer.
> We already do this in many cases, all other ones need to be converted
> to pass NULL.

M  gotd/parse.y                                             |  14+  1-
M  gotsysd/libexec/gotsys-repo-create/gotsys-repo-create.c  |   6+  2-
M  gotsysd/parse.y                                          |  27+  2-

3 files changed, 47 insertions(+), 5 deletions(-)

commit - 21052e4a4742a630c583361b135296c061b6ea55
commit + b52e6d7b066bfba53c5b32ed47de6192b9999863
blob - 44d3566166c62cfe42884a1c13490e84ff78e37d
blob + 5a674f1db04dd83b19fe9a04e04a96d22e0ad79b
--- gotd/parse.y
+++ gotd/parse.y
@@ -675,13 +675,15 @@ repository	: REPOSITORY STRING {
 repoopts1	: PATH STRING {
 			if (gotd_proc_id == GOTD_PROC_GOTD ||
 			    gotd_proc_id == GOTD_PROC_GITWRAPPER) {
+				char *repo_path;
 				if (!got_path_is_absolute($2)) {
 					yyerror("%s: path %s is not absolute",
 					    __func__, $2);
 					free($2);
 					YYERROR;
 				}
-				if (realpath($2, new_repo->path) == NULL) {
+				repo_path = realpath($2, NULL);
+				if (repo_path == NULL) {
 					/*
 					 * To give admins a chance to create
 					 * missing repositories at run-time
@@ -707,8 +709,19 @@ repoopts1	: PATH STRING {
 					    sizeof(new_repo->path)) >=
 					    sizeof(new_repo->path)) {
 						yyerror("path too long");
+						free($2);
 						YYERROR;
 					}
+				} else {
+					if (strlcpy(new_repo->path, repo_path,
+					    sizeof(new_repo->path)) >=
+					    sizeof(new_repo->path)) {
+						yyerror("path too long");
+						free(repo_path);
+						free($2);
+						YYERROR;
+					}
+					free(repo_path);
 				}
 			}
 			free($2);
blob - d8abeaf2d0a5fc1569525fd0be4ea5b228d59506
blob + b8bf3241a098461bb0a4aea4ad824b5a7cc7a996
--- gotsysd/libexec/gotsys-repo-create/gotsys-repo-create.c
+++ gotsysd/libexec/gotsys-repo-create/gotsys-repo-create.c
@@ -387,7 +387,7 @@ main(int argc, char **argv)
 	struct gotsysd_imsgev iev;
 	struct event evsigint, evsigterm, evsighup, evsigusr1;
 	struct passwd *pw;
-	char *username;
+	char *username, *p;
 	struct stat sb;
 #if 0
 	static int attached;
@@ -409,8 +409,12 @@ main(int argc, char **argv)
 		errx(1, "usage: %s username repos_path", getprogname());
 
 	username = argv[1];
-	if (realpath(argv[2], repos_path) == NULL)
+	p = realpath(argv[2], NULL);
+	if (p == NULL)
 		err(1, "realpath %s", argv[2]);
+	if (strlcpy(repos_path, p, sizeof(repos_path)) >= sizeof(repos_path))
+		err(1, "path too long: %s", p);
+	free(p);
 
 	pw = getpwnam(username);
 	if (pw == NULL)
blob - 7b32606e939f3b783aa31c929c68ff3cfc2e0bef
blob + 0a0b6f036a36391125168e6314bdc58c360ae83e
--- gotsysd/parse.y
+++ gotsysd/parse.y
@@ -191,11 +191,14 @@ listen_addr	: '*' { $$ = NULL; }
 		;
 
 main		: LISTEN ON STRING {
+			char *p;
+
 			if (!got_path_is_absolute($3))
 				yyerror("bad unix socket path \"%s\": "
 				    "must be an absolute path", $3);
 
-			if (realpath($3, gotsysd->unix_socket_path) == NULL) {
+			p = realpath($3, NULL);
+			if (p == NULL) {
 				if (errno != ENOENT && errno != EACCES) {
 					yyerror("realpath %s: %s", $3,
 					    strerror(errno));
@@ -211,6 +214,17 @@ main		: LISTEN ON STRING {
 					free($3);
 					YYERROR;
 				}
+			} else {
+				if (strlcpy(gotsysd->unix_socket_path, p,
+				    sizeof(gotsysd->unix_socket_path)) >=
+				    sizeof(gotsysd->unix_socket_path)) {
+					yyerror("unix socket path too long: %s",
+					    p);
+					free(p);
+					free($3);
+					YYERROR;
+				}
+				free(p);
 			}
 			free($3);
 		}
@@ -235,6 +249,8 @@ main		: LISTEN ON STRING {
 			free($3);
 		}
 		| REPOSITORY DIRECTORY STRING {
+			char *p;
+
 			if (!got_path_is_absolute($3)) {
 				yyerror("bad path \"%s\": "
 				    "must be an absolute path", $3);
@@ -242,11 +258,20 @@ main		: LISTEN ON STRING {
 				YYERROR;
 			}
 
-			if (realpath($3, gotsysd->repos_path) == NULL) {
+			p = realpath($3, NULL);
+			if (p == NULL) {
 				yyerror("realpath %s: %s", $3, strerror(errno));
 				free($3);
 				YYERROR;
 			}
+			if (strlcpy(gotsysd->repos_path, p,
+			    sizeof(gotsysd->repos_path)) >=
+			    sizeof(gotsysd->repos_path)) {
+				yyerror("repository path too long: %s", p);
+				free(p);
+				free($3);
+				YYERROR;
+			}
 			free($3);
 		}
 		| UID RANGE NUMBER NUMBER {