Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!sun-barr!olivea!samsung!zaphod.mps.ohio-state.edu!caen!hellgate.utah.edu!snake.utah.edu!forys From: forys@snake.utah.edu (Jeff Forys) Newsgroups: comp.mail.sendmail Subject: Sendmail 5.65 can loop on certain addresses +FIX Keywords: sendmail, bug, fix Message-ID: <1990Nov10.014841.5592@hellgate.utah.edu> Date: 10 Nov 90 08:48:40 GMT Organization: University of Utah CS Dept Lines: 120 Index: usr.lib/sendmail/src/parseaddr.c 4.3BSD This applies to all known versions of sendmail (through "5.65"). Description: Sendmail reserves characters in the range 020 - 036 for coding its rewrite rules. If one of these characters shows up in an address, the results are unpredictable (from a user's point of view). Specifically, an address containing a "replacement on RHS" rule can cause sendmail to go into an infinite loop while processing various rewrite rules. I suppose this could be used for a denial-of-service attack; if an evil-minded person fired off a bunch of these in your direction, you would end up with an equal number of sendmail processes churning endlessly away on your CPU. Of course, whence such an "attack" originates would be painfully obvious! Repeat-By: This is configuration-file dependent, however if your RuleSet 3 looks similar to what Berkeley distributes, you can get your sendmail to loop on the rule: R$+<$+@$+> $1$2<@$3> move gaze right by doing: % sendmail -bs MAIL FROM: user RCPT TO: or, under addess test mode: % sendmail -bt 3 The angle brackets are important (in this particular example). The "^U" should, of course, be an ASCII NAK (i.e. MATCHREPL). Fix: Apply the following patches; they should be self-explanatory. *** /tmp/,RCSt1003663 Tue Nov 6 01:20:48 1990 --- parseaddr.c Tue Nov 6 00:55:21 1990 *************** *** 86,91 **** --- 86,94 ---- if (tTd(20, 1)) printf("\n--parseaddr(%s)\n", addr); + if (invalidaddr(addr)) + return(NULL); + pvp = prescan(addr, delim, pvpbuf); if (pvp == NULL) return (NULL); *************** *** 220,225 **** --- 223,267 ---- if (!bitnset(M_USR_UPPER, m->m_flags)) makelower(a->q_user); + } + /* + ** INVALIDADDR -- check an address string for invalid control characters. + ** + ** Parameters: + ** addr -- address string to be checked. + ** + ** Returns: + ** TRUE if address string could cause problems, FALSE o/w. + ** + ** Side Effects: + ** ExitStat may be changed and an error message generated. + */ + + invalidaddr(addr) + char *addr; + { + register char *cp; + extern int errno; + + /* make sure error messages don't have garbage on them */ + errno = 0; + + /* + ** Sendmail reserves characters 020 - 036 for rewriting rules + ** which can cause havoc (e.g. infinite rewriting loops) if + ** one shows up at the wrong time. If any of these characters + ** appear in an address, the address is deemed "invalid" and + ** an error message is generated. + */ + + for (cp = addr; *cp; cp++) + if ((*cp >= MATCHZANY && *cp <= HOSTEND) || *cp == '\001') { + setstat(EX_USAGE); + usrerr("address contained invalid control char(s)"); + return (TRUE); + } + + return(FALSE); } /* ** PRESCAN -- Prescan name and make it canonical *** /tmp/,RCSt1003691 Tue Nov 6 01:21:07 1990 --- main.c Tue Nov 6 00:55:21 1990 *************** *** 586,591 **** --- 586,593 ---- if (*p == '\0') continue; *p = '\0'; + if (invalidaddr(p+1)) + continue; do { extern char **prescan(); --- Jeff Forys, Unv of Utah/Salt Lake, Comp Sci Dept +1 801 581 4280 forys@cs.utah.edu -or- ..!{boulder,cs.utexas.edu}!utah-cs!forys