COMMAND

    sendmail

SYSTEMS AFFECTED

    Sendmail

PROBLEM

    Michal  Zalewski  found  following.   Sendmail,  launched with -bt
    command-line switch, enters it's special "address test" mode.   It
    is  not  dropping  root  privledges,  and  accepting user-supplied
    input.   Several  commands  provided  in  this  mode  had   broken
    implementation.   One of  the most  serious bugs  is missing check
    before calling setclass() functions.

SOLUTION

    Guys at  sendmail.org do  not believe  this is  exploitable -- the
    .D command does not suffer from  this bug and the .C command  only
    uses the character for an index  into a bitmap.  You can  write to
    four bytes of  memory.  On  some platforms, it's  well outside the
    range of usable memory.  On others, it is the adjacent four  bytes
    in the Stab.   It may corrupt  other data in  the Stab but  should
    not be exploitable.

    However, they will be releasing 8.11.2 in the near future to fix
    this bug.  For those who prefer not to wait - patch is below:

    Also included with the patch is a new FFR (for future release)  to
    drop privileges when entering address  test mode.  To enable  this
    feature, compile with:

        APPENDDEF(`conf_sendmail_ENVDEF', `-D_FFR_TESTMODE_DROP_PRIVS')

    in your devtools/Site/site.config.m4 file.  This will most  likely
    become the default behavior in 8.12.

    --- macro.c	2000/09/17 17:04:26	8.40.16.2
    +++ macro.c	2000/10/09 17:30:04
    @@ -377,7 +377,7 @@
 			    *ep = p + 1;
 		    if (tTd(35, 14))
 			    dprintf("%c\n", *p);
    -		return *p;
    +		return ((unsigned int)*p) & 0xff;
 	    }
 	    bp = mbuf;
 	    while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof mbuf - 1])
    @@ -401,7 +401,7 @@
 	    else if (mbuf[1] == '\0')
 	    {
 		    /* ${x} == $x */
    -		mid = mbuf[0];
    +		mid = ((unsigned int)mbuf[0]) & 0xff;
 		    p++;
 	    }
 	    else
    @@ -428,6 +428,11 @@
 	    }
 	    if (ep != NULL)
 		    *ep = p;
    +	if (mid < 0 || mid > MAXMACROID)
    +	{
    +		syserr("Unable to assign macro/class ID (mid = 0x%x)", mid);
    +		mid = 0;
    +	}
 	    if (tTd(35, 14))
 		    dprintf("0x%x\n", mid);
 	    return mid;
    --- main.c	2000/09/26 01:30:38	8.485.4.27
    +++ main.c	2000/10/09 17:30:05
    @@ -1681,6 +1681,15 @@
 	    {
 		    char buf[MAXLINE];
    
    +#if _FFR_TESTMODE_DROP_PRIVS
    +		dp = drop_privileges(TRUE);
    +		if (dp != EX_OK)
    +		{
    +			CurEnv->e_id = NULL;
    +			finis(TRUE, dp);
    +		}
    +#endif /* _FFR_TESTMODE_DROP_PRIVS */
    +
 		    if (isatty(fileno(stdin)))
 			    Verbose = 2;
    
    --- readcf.c	2000/09/28 01:31:16	8.382.4.27
    +++ readcf.c	2000/10/09 17:30:07
    @@ -3195,7 +3195,7 @@
 			    dprintf("setclass(%s, %s)\n", macname(class), str);
    
 		    s = stab(str, ST_CLASS, ST_ENTER);
    -		setbitn(class, s->s_class);
    +		setbitn(((unsigned int)class) & 0xff, s->s_class);
 	    }
     }
     /*
    --- stab.c	2000/06/05 21:46:59	8.40.16.2
    +++ stab.c	2000/10/09 17:30:07
    @@ -326,6 +326,7 @@
 	    register STAB **shead;
 	    register STAB *s;
    
    +	dst = ((unsigned int)dst) & 0xff;
 	    for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
 	    {
 		    for (s = *shead; s != NULL; s = s->s_next)