Download raw body.
gotsysd: use PATH_MAX for realpath
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 {
gotsysd: use PATH_MAX for realpath