sendmail gecos oflow -- found by mudge, this fix by downsj. I knew about this
authorderaadt <deraadt@openbsd.org>
Thu, 12 Sep 1996 19:25:42 +0000 (19:25 +0000)
committerderaadt <deraadt@openbsd.org>
Thu, 12 Sep 1996 19:25:42 +0000 (19:25 +0000)
hole a month ago. OpenBSD is not vulnerable because you cannot set a gecos that
long -- bitblt and I fixed chfn & the other tools when we became aware of the
hole; we did not fix sendmail to avoid bringing attention to the sendmail hole

usr.sbin/sendmail/src/envelope.c
usr.sbin/sendmail/src/recipient.c
usr.sbin/sendmail/src/util.c

index 4bf7ac2..1cd3b56 100644 (file)
@@ -777,7 +777,8 @@ setsender(from, e, delimptr, internal)
                            strcmp(pw->pw_name, e->e_from.q_user) == 0 &&
                            !internal)
                        {
-                               buildfname(pw->pw_gecos, e->e_from.q_user, buf);
+                               buildfname(pw->pw_gecos, e->e_from.q_user,
+                                   buf, sizeof buf);
                                if (buf[0] != '\0')
                                        FullName = newstr(buf);
                        }
index 79126e9..90e3e5a 100644 (file)
@@ -535,7 +535,7 @@ recipient(a, sendq, aliaslevel, e)
                        a->q_gid = pw->pw_gid;
                        a->q_ruser = newstr(pw->pw_name);
                        a->q_flags |= QGOODUID;
-                       buildfname(pw->pw_gecos, pw->pw_name, nbuf);
+                       buildfname(pw->pw_gecos, pw->pw_name, nbuf, sizeof nbuf);
                        if (nbuf[0] != '\0')
                                a->q_fullname = newstr(nbuf);
                        if (!usershellok(pw->pw_name, pw->pw_shell))
@@ -743,7 +743,7 @@ finduser(name, fuzzyp)
                }
 # endif
 
-               buildfname(pw->pw_gecos, pw->pw_name, buf);
+               buildfname(pw->pw_gecos, pw->pw_name, buf, sizeof buf);
                if (strchr(buf, ' ') != NULL && !strcasecmp(buf, name))
                {
                        if (tTd(29, 4))
index 096f519..0610423 100644 (file)
@@ -383,10 +383,11 @@ makelower(p)
 */
 
 void
-buildfname(gecos, login, buf)
+buildfname(gecos, login, buf, bufsiz)
        register char *gecos;
        char *login;
        char *buf;
+       int bufsiz;
 {
        register char *p;
        register char *bp = buf;
@@ -395,22 +396,13 @@ buildfname(gecos, login, buf)
        if (*gecos == '*')
                gecos++;
 
-       /* find length of final string */
-       l = 0;
-       for (p = gecos; *p != '\0' && *p != ',' && *p != ';' && *p != '%'; p++)
-       {
-               if (*p == '&')
-                       l += strlen(login);
-               else
-                       l++;
-       }
-
-       /* now fill in buf */
-       for (p = gecos; *p != '\0' && *p != ',' && *p != ';' && *p != '%'; p++)
+       for (p = gecos; *p != '\0' && *p != ',' && *p != ';' && *p != '%'
+               && ((bp - buf) <= (bufsiz - 1)); p++)
        {
                if (*p == '&')
                {
-                       (void) strcpy(bp, login);
+                       (void) strncpy(bp, login, (bufsiz - (bp - buf) - 1));
+                       buf[bufsiz - 1] = '\0';
                        *bp = toupper(*bp);
                        while (*bp != '\0')
                                bp++;