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 <d...@freebsd.org>
AuthorDate: 2025-07-28 15:28:26 +0000
Commit:     Dag-Erling Smørgrav <d...@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);

Reply via email to