Properly patch up dirname()/basename() calls to not clobber ent->log.

It turns out that we had a couple of more calls to dirname()/basename()
in newsyslog(8) that assume the input isn't clobbered. This is bad,
because it apparently breaks log rotation now that the new dirname()
implementation has been merged.

Fix this by first copying the input and then calling
dirname()/basename(). While there, improve the naming of variables in
this function a bit.

Reported by:	Ryan Steinmetz, gjb
Reviewed by:	bdrewery, allanjude
Differential Revision:	https://reviews.freebsd.org/D7838
This commit is contained in:
Ed Schouten 2016-09-09 07:10:50 +00:00
parent 01decb509d
commit 23e591f485
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305651

View File

@ -1510,11 +1510,11 @@ validate_old_timelog(int fd, const struct dirent *dp, const char *logfname,
static void static void
delete_oldest_timelog(const struct conf_entry *ent, const char *archive_dir) delete_oldest_timelog(const struct conf_entry *ent, const char *archive_dir)
{ {
char *logfname, *s, *dir, errbuf[80]; char *basebuf, *dirbuf, errbuf[80];
const char *base, *dir;
int dir_fd, i, logcnt, max_logcnt; int dir_fd, i, logcnt, max_logcnt;
struct oldlog_entry *oldlogs; struct oldlog_entry *oldlogs;
struct dirent *dp; struct dirent *dp;
const char *cdir;
struct tm tm; struct tm tm;
DIR *dirp; DIR *dirp;
@ -1522,19 +1522,19 @@ delete_oldest_timelog(const struct conf_entry *ent, const char *archive_dir)
max_logcnt = MAX_OLDLOGS; max_logcnt = MAX_OLDLOGS;
logcnt = 0; logcnt = 0;
if (archive_dir != NULL && archive_dir[0] != '\0') if (archive_dir != NULL && archive_dir[0] != '\0') {
cdir = archive_dir; dirbuf = NULL;
else dir = archive_dir;
if ((cdir = dirname(ent->log)) == NULL) } else {
err(1, "dirname()"); if ((dirbuf = strdup(ent->log)) == NULL)
if ((dir = strdup(cdir)) == NULL) err(1, "strdup()");
err(1, "strdup()"); dir = dirname(dirbuf);
}
if ((s = basename(ent->log)) == NULL) if ((basebuf = strdup(ent->log)) == NULL)
err(1, "basename()");
if ((logfname = strdup(s)) == NULL)
err(1, "strdup()"); err(1, "strdup()");
if (strcmp(logfname, "/") == 0) base = basename(basebuf);
if (strcmp(base, "/") == 0)
errx(1, "Invalid log filename - became '/'"); errx(1, "Invalid log filename - became '/'");
if (verbose > 2) if (verbose > 2)
@ -1545,7 +1545,7 @@ delete_oldest_timelog(const struct conf_entry *ent, const char *archive_dir)
err(1, "Cannot open log directory '%s'", dir); err(1, "Cannot open log directory '%s'", dir);
dir_fd = dirfd(dirp); dir_fd = dirfd(dirp);
while ((dp = readdir(dirp)) != NULL) { while ((dp = readdir(dirp)) != NULL) {
if (validate_old_timelog(dir_fd, dp, logfname, &tm) == 0) if (validate_old_timelog(dir_fd, dp, base, &tm) == 0)
continue; continue;
/* /*
@ -1610,8 +1610,8 @@ delete_oldest_timelog(const struct conf_entry *ent, const char *archive_dir)
free(oldlogs[i].fname); free(oldlogs[i].fname);
} }
free(oldlogs); free(oldlogs);
free(logfname); free(dirbuf);
free(dir); free(basebuf);
} }
/* /*