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)