--- admin.c.orig 2016-02-06 23:25:25.000000000 +0100 +++ admin.c 2020-10-23 17:31:04.762476000 +0200 @@ -246,12 +246,17 @@ struct cvs_file *ocf; struct rcs_access *acp; int ofd; - char *d, *f, fpath[PATH_MAX], repo[PATH_MAX]; + char *d, dbuf[PATH_MAX], *f, fbuf[PATH_MAX]; + char fpath[PATH_MAX], repo[PATH_MAX]; - - if ((f = basename(oldfilename)) == NULL) + if (strlcpy(fbuf, oldfilename, sizeof(fbuf)) >= sizeof(fbuf)) + fatal("cvs_admin_local: truncation"); + if ((f = basename(fbuf)) == NULL) fatal("cvs_admin_local: basename failed"); - if ((d = dirname(oldfilename)) == NULL) + + if (strlcpy(dbuf, oldfilename, sizeof(dbuf)) >= sizeof(dbuf)) + fatal("cvs_admin_local: truncation"); + if ((d = dirname(dbuf)) == NULL) fatal("cvs_admin_local: dirname failed"); cvs_get_repository_path(d, repo, PATH_MAX); --- checkout.c.orig 2016-02-06 23:25:25.000000000 +0100 +++ checkout.c 2020-10-23 17:31:04.763063000 +0200 @@ -239,7 +239,7 @@ struct module_checkout *mc; struct cvs_ignpat *ip; struct cvs_filelist *fl, *nxt; - char repo[PATH_MAX], fpath[PATH_MAX], *f[1]; + char repo[PATH_MAX], fpath[PATH_MAX], path[PATH_MAX], *f[1]; build_dirs = print_stdout ? 0 : 1; @@ -329,14 +329,25 @@ cr.flags = flags; if (!(mc->mc_flags & MODULE_ALIAS)) { + if (strlcpy(path, fl->file_path, + sizeof(path)) >= sizeof(path)) + fatal("%s: truncation", + __func__); module_repo_root = - xstrdup(dirname(fl->file_path)); + xstrdup(dirname(path)); d = wdir; + if (strlcpy(path, fl->file_path, + sizeof(path)) >= sizeof(path)) + fatal("%s: truncation", + __func__); (void)xsnprintf(fpath, sizeof(fpath), - "%s/%s", d, - basename(fl->file_path)); + "%s/%s", d, basename(path)); } else { - d = dirname(wdir); + if (strlcpy(path, wdir, + sizeof(path)) >= sizeof(path)) + fatal("%s: truncation", + __func__); + d = dirname(path); strlcpy(fpath, fl->file_path, sizeof(fpath)); } @@ -387,7 +398,7 @@ static int checkout_classify(const char *repo, const char *arg) { - char *d, *f, fpath[PATH_MAX]; + char *d, dbuf[PATH_MAX], *f, fbuf[PATH_MAX], fpath[PATH_MAX]; struct stat sb; if (stat(repo, &sb) == 0) { @@ -395,8 +406,13 @@ return CVS_DIR; } - d = dirname(repo); - f = basename(repo); + if (strlcpy(dbuf, repo, sizeof(dbuf)) >= sizeof(dbuf)) + fatal("checkout_classify: truncation"); + d = dirname(dbuf); + + if (strlcpy(fbuf, repo, sizeof(fbuf)) >= sizeof(fbuf)) + fatal("checkout_classify: truncation"); + f = basename(fbuf); (void)xsnprintf(fpath, sizeof(fpath), "%s/%s%s", d, f, RCS_FILE_EXT); if (stat(fpath, &sb) == 0) { --- client.c.orig 2016-02-06 23:25:25.000000000 +0100 +++ client.c 2020-10-23 17:31:04.763738000 +0200 @@ -157,6 +157,7 @@ { CVSENTRIES *entlist; char *entry, *parent, *base, *p; + char basebuf[PATH_MAX], parentbuf[PATH_MAX]; STRIP_SLASH(data); @@ -174,10 +175,14 @@ if (cvs_cmdop == CVS_OP_EXPORT) return; - if ((base = basename(data)) == NULL) + if (strlcpy(basebuf, data, sizeof(basebuf)) >= sizeof(basebuf)) + fatal("client_check_directory: truncation"); + if ((base = basename(basebuf)) == NULL) fatal("client_check_directory: overflow"); - if ((parent = dirname(data)) == NULL) + if (strlcpy(parentbuf, data, sizeof(parentbuf)) >= sizeof(parentbuf)) + fatal("client_check_directory: truncation"); + if ((parent = dirname(parentbuf)) == NULL) fatal("client_check_directory: overflow"); if (!strcmp(parent, ".")) @@ -798,7 +803,7 @@ struct timeval tv[2]; struct tm datetm; char timebuf[CVS_TIME_BUFSZ], *repo, *rpath, *entry, *mode; - char *len, *fpath, *wdir; + char *len, *fpath, *wdir, wdirbuf[PATH_MAX]; if (data == NULL) fatal("Missing argument for Merged"); @@ -819,7 +824,9 @@ fatal("received a repository path that is too short"); fpath = rpath + strlen(repo) + 1; - if ((wdir = dirname(fpath)) == NULL) + if (strlcpy(wdirbuf, fpath, sizeof(wdirbuf)) >= sizeof(wdirbuf)) + fatal("cvs_client_merged: truncation"); + if ((wdir = dirname(wdirbuf)) == NULL) fatal("cvs_client_merged: dirname: %s", strerror(errno)); free(repo); --- file.c.orig 2016-02-06 23:25:25.000000000 +0100 +++ file.c 2020-10-23 17:31:04.764339000 +0200 @@ -266,7 +266,8 @@ struct stat st; struct cvs_file *cf; struct cvs_filelist *l, *nxt; - char *d, *f, repo[PATH_MAX], fpath[PATH_MAX]; + char *d, dbuf[PATH_MAX], *f, fbuf[PATH_MAX]; + char repo[PATH_MAX], fpath[PATH_MAX]; for (l = RB_MIN(cvs_flisthead, fl); l != NULL; l = nxt) { if (cvs_quit) @@ -275,9 +276,14 @@ cvs_log(LP_TRACE, "cvs_file_walklist: element '%s'", l->file_path); - if ((f = basename(l->file_path)) == NULL) + if (strlcpy(fbuf, l->file_path, sizeof(fbuf)) >= sizeof(fbuf)) + fatal("cvs_file_walklist: truncation"); + if ((f = basename(fbuf)) == NULL) fatal("cvs_file_walklist: basename failed"); - if ((d = dirname(l->file_path)) == NULL) + + if (strlcpy(dbuf, l->file_path, sizeof(dbuf)) >= sizeof(dbuf)) + fatal("cvs_file_walklist: truncation"); + if ((d = dirname(dbuf)) == NULL) fatal("cvs_file_walklist: dirname failed"); type = l->type; --- logmsg.c.orig 2016-02-06 23:25:25.000000000 +0100 +++ logmsg.c 2020-10-23 17:31:04.764897000 +0200 @@ -100,6 +100,7 @@ struct cvs_filelist *cf; struct stat st1, st2; char *fpath, *logmsg, repo[PATH_MAX]; + char *f, path[PATH_MAX]; struct stat st; struct trigger_list *line_list; struct trigger_line *line; @@ -165,28 +166,46 @@ if (added != NULL && !RB_EMPTY(added)) { fprintf(fp, "%s Added Files:", CVS_LOGMSG_PREFIX); - RB_FOREACH(cf, cvs_flisthead, added) - fprintf(fp, "\n%s\t%s", CVS_LOGMSG_PREFIX, - dir != NULL ? basename(cf->file_path) : - cf->file_path); + RB_FOREACH(cf, cvs_flisthead, added) { + f = cf->file_path; + if (dir != NULL) { + if (strlcpy(path, f, sizeof(path)) >= + sizeof(path)) + fatal("cvs_logmsg_create: truncation"); + f = basename(path); + } + fprintf(fp, "\n%s\t%s", CVS_LOGMSG_PREFIX, f); + } fputs("\n", fp); } if (removed != NULL && !RB_EMPTY(removed)) { fprintf(fp, "%s Removed Files:", CVS_LOGMSG_PREFIX); - RB_FOREACH(cf, cvs_flisthead, removed) - fprintf(fp, "\n%s\t%s", CVS_LOGMSG_PREFIX, - dir != NULL ? basename(cf->file_path) : - cf->file_path); + RB_FOREACH(cf, cvs_flisthead, removed) { + f = cf->file_path; + if (dir != NULL) { + if (strlcpy(path, f, sizeof(path)) >= + sizeof(path)) + fatal("cvs_logmsg_create: truncation"); + f = basename(path); + } + fprintf(fp, "\n%s\t%s", CVS_LOGMSG_PREFIX, f); + } fputs("\n", fp); } if (modified != NULL && !RB_EMPTY(modified)) { fprintf(fp, "%s Modified Files:", CVS_LOGMSG_PREFIX); - RB_FOREACH(cf, cvs_flisthead, modified) - fprintf(fp, "\n%s\t%s", CVS_LOGMSG_PREFIX, - dir != NULL ? basename(cf->file_path) : - cf->file_path); + RB_FOREACH(cf, cvs_flisthead, modified) { + f = cf->file_path; + if (dir != NULL) { + if (strlcpy(path, f, sizeof(path)) >= + sizeof(path)) + fatal("cvs_logmsg_create: truncation"); + f = basename(path); + } + fprintf(fp, "\n%s\t%s", CVS_LOGMSG_PREFIX, f); + } fputs("\n", fp); } --- rcs.c.orig 2016-02-06 23:25:25.000000000 +0100 +++ rcs.c 2020-10-23 17:31:04.765876000 +0200 @@ -2190,8 +2190,8 @@ int kwtype; u_int j, found; const u_char *c, *start, *fin, *end; - char *kwstr; - char expbuf[256], buf[256]; + char *kwstr, *rcsfile_basename; + char expbuf[256], buf[256], path[PATH_MAX]; size_t clen, kwlen, len, tlen; kwtype = 0; @@ -2209,6 +2209,10 @@ /* Final character in buffer. */ fin = c + len - 1; + if (strlcpy(path, rcsfile, sizeof(path)) >= sizeof(path)) + fatal("rcs_kwexp_line: truncation"); + rcsfile_basename = basename(path); + /* * Keyword formats: * $Keyword$ @@ -2307,7 +2311,7 @@ if (mode & RCS_KWEXP_VAL) { if (kwtype & RCS_KW_RCSFILE) { if (!(kwtype & RCS_KW_FULLPATH)) - (void)strlcat(expbuf, basename(rcsfile), + (void)strlcat(expbuf, rcsfile_basename, sizeof(expbuf)); else (void)strlcat(expbuf, rcsfile, @@ -2383,7 +2387,7 @@ /* Log line */ if (!(kwtype & RCS_KW_FULLPATH)) (void)strlcat(expbuf, - basename(rcsfile), sizeof(expbuf)); + rcsfile_basename, sizeof(expbuf)); else (void)strlcat(expbuf, rcsfile, sizeof(expbuf)); --- server.c.orig 2016-02-06 23:25:25.000000000 +0100 +++ server.c 2020-10-23 17:31:04.766443000 +0200 @@ -324,6 +324,7 @@ { CVSENTRIES *entlist; char *dir, *repo, *parent, *entry, *dirn, *p; + char parentbuf[PATH_MAX], dirnbuf[PATH_MAX]; if (current_cvsroot == NULL) fatal("No Root specified for Directory"); @@ -350,10 +351,14 @@ cvs_mkpath(p, NULL); - if ((dirn = basename(p)) == NULL) + if (strlcpy(dirnbuf, p, sizeof(dirnbuf)) >= sizeof(dirnbuf)) + fatal("cvs_server_directory: truncation"); + if ((dirn = basename(dirnbuf)) == NULL) fatal("cvs_server_directory: %s", strerror(errno)); - if ((parent = dirname(p)) == NULL) + if (strlcpy(parentbuf, p, sizeof(parentbuf)) >= sizeof(parentbuf)) + fatal("cvs_server_directory: truncation"); + if ((parent = dirname(parentbuf)) == NULL) fatal("cvs_server_directory: %s", strerror(errno)); if (strcmp(parent, ".")) {