git: 6ca3734e928c - stable/13 - comsat: Don't read arbitrary files
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 05 Aug 2025 11:52:49 UTC
The branch stable/13 has been updated by des:
URL: https://cgit.FreeBSD.org/src/commit/?id=6ca3734e928cc82f2f91b991be28c9900b2b4a07
commit 6ca3734e928cc82f2f91b991be28c9900b2b4a07
Author: Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-07-28 15:28:26 +0000
Commit: Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-08-05 11:52:28 +0000
comsat: Don't read arbitrary files
When processing a notification, instead of accepting any file name
that doesn't begin with a slash, accept only file names that don't
contain any slashes at all. This makes it possible to notify a
user about a mailbox that doesn't bear their name, as long as they
are permitted to read it, but prevents comsat from reading files
outside the mail spool.
PR: 270404
MFC after: 1 week
Reviewed by: emaste
Differential Revision: https://reviews.freebsd.org/D51580
(cherry picked from commit 4a4338d94401f0012380d4f1a4d332bd6d44fa8e)
comsat: Don't return from the child
Fixes: 91629228e3df
MFC after: 1 week
Reviewed by: emaste
Differential Revision: https://reviews.freebsd.org/D51581
(cherry picked from commit e40a2c4927a8068d7b6adee69c90ae3be8efc4df)
---
libexec/comsat/comsat.c | 40 ++++++++++++++--------------------------
1 file changed, 14 insertions(+), 26 deletions(-)
diff --git a/libexec/comsat/comsat.c b/libexec/comsat/comsat.c
index 2358336be61a..f40123a5ef09 100644
--- a/libexec/comsat/comsat.c
+++ b/libexec/comsat/comsat.c
@@ -125,29 +125,24 @@ mailfor(char *name)
char *file;
off_t offset;
int folder;
- char buf[sizeof(_PATH_MAILDIR) + sizeof(utp->ut_user) + 1];
- char buf2[sizeof(_PATH_MAILDIR) + sizeof(utp->ut_user) + 1];
+ char buf[MAXPATHLEN];
- if (!(cp = strchr(name, '@')))
+ if ((cp = strchr(name, '@')) == NULL)
return;
*cp = '\0';
offset = strtoll(cp + 1, NULL, 10);
- if (!(cp = strchr(cp + 1, ':')))
- file = name;
- else
- file = cp + 1;
- sprintf(buf, "%s/%.*s", _PATH_MAILDIR, (int)sizeof(utp->ut_user),
- name);
- if (*file != '/') {
- sprintf(buf2, "%s/%.*s", _PATH_MAILDIR,
- (int)sizeof(utp->ut_user), file);
- file = buf2;
+ if ((cp = strchr(cp + 1, ':')) != NULL &&
+ strchr((file = cp + 1), '/') == NULL) {
+ snprintf(buf, sizeof(buf), "%s/%s", _PATH_MAILDIR, file);
+ folder = 1;
+ } else {
+ snprintf(buf, sizeof(buf), "%s/%s", _PATH_MAILDIR, name);
+ folder = 0;
}
- folder = strcmp(buf, file);
setutxent();
while ((utp = getutxent()) != NULL)
if (utp->ut_type == USER_PROCESS && !strcmp(utp->ut_user, name))
- notify(utp, file, offset, folder);
+ notify(utp, buf, offset, folder);
endutxent();
}
@@ -171,8 +166,7 @@ notify(struct utmpx *utp, char file[], off_t offset, int folder)
utp->ut_line);
return;
}
- (void)snprintf(tty, sizeof(tty), "%s%.*s",
- _PATH_DEV, (int)sizeof(utp->ut_line), utp->ut_line);
+ (void)snprintf(tty, sizeof(tty), "%s%s", _PATH_DEV, utp->ut_line);
if (stat(tty, &stb) == -1 || !(stb.st_mode & (S_IXUSR | S_IXGRP))) {
dsyslog(LOG_DEBUG, "%s: wrong mode on %s", utp->ut_user, tty);
return;
@@ -199,26 +193,20 @@ notify(struct utmpx *utp, char file[], off_t offset, int folder)
initgroups(p->pw_name, p->pw_gid) == -1 ||
setgid(p->pw_gid) == -1 ||
setuid(p->pw_uid) == -1)
- return;
+ _exit(1);
- switch (stb.st_mode & (S_IXUSR | S_IXGRP)) {
- case S_IXUSR:
- case (S_IXUSR | S_IXGRP):
+ if (stb.st_mode & S_IXUSR) {
(void)fprintf(tp,
"%s\007New mail for %s@%.*s\007 has arrived%s%s%s:%s----%s",
cr, utp->ut_user, (int)sizeof(hostname), hostname,
folder ? cr : "", folder ? "to " : "", folder ? file : "",
cr, cr);
jkfprintf(tp, file, offset);
- break;
- case S_IXGRP:
+ } else if (stb.st_mode & S_IXGRP) {
(void)fprintf(tp, "\007");
(void)fflush(tp);
(void)sleep(1);
(void)fprintf(tp, "\007");
- break;
- default:
- break;
}
(void)fclose(tp);
_exit(0);