Check the patch obtained from sendmail.org for the header denial-of-service
attack into the vendor branch. It is a little unusual doing it this way but it will eliminate (or minimize anyway) conflicts when 8.9.3 comes out. Obtained from: sendmail.org (as posted on bugtraq, but without broken tabs)
This commit is contained in:
parent
065a643db3
commit
25bab6e904
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/sendmail/dist/; revision=43148 svn path=/vendor/sendmail/8.9.2-header/; revision=43150; tag=vendor/sendmail/8.9.2-header
@ -478,6 +478,10 @@ ifdef(`confMAX_MIME_HEADER_LENGTH',
|
||||
`# Maximum MIME header length to protect MUAs
|
||||
O MaxMimeHeaderLength=confMAX_MIME_HEADER_LENGTH
|
||||
')
|
||||
ifdef(`confMAX_HEADER_LINES',
|
||||
`# Maximum number of header lines and header line length limit
|
||||
O MaxHeaderLines=confMAX_HEADER_LINES
|
||||
')
|
||||
|
||||
###########################
|
||||
# Message precedences #
|
||||
|
@ -57,6 +57,7 @@ static EVENT *CollectTimeout;
|
||||
#define MS_UFROM 0 /* reading Unix from line */
|
||||
#define MS_HEADER 1 /* reading message header */
|
||||
#define MS_BODY 2 /* reading message body */
|
||||
#define MS_DISCARD 3 /* discarding rest of message */
|
||||
|
||||
void
|
||||
collect(fp, smtpmode, hdrp, e)
|
||||
@ -77,6 +78,8 @@ collect(fp, smtpmode, hdrp, e)
|
||||
volatile int istate;
|
||||
volatile int mstate;
|
||||
u_char *volatile pbp;
|
||||
int nhdrlines = 0;
|
||||
int hdrlinelen = 0;
|
||||
u_char peekbuf[8];
|
||||
char dfname[MAXQFNAME];
|
||||
char bufbuf[MAXLINE];
|
||||
@ -198,6 +201,7 @@ collect(fp, smtpmode, hdrp, e)
|
||||
switch (istate)
|
||||
{
|
||||
case IS_BOL:
|
||||
hdrlinelen = 0;
|
||||
if (c == '.')
|
||||
{
|
||||
istate = IS_DOT;
|
||||
@ -262,12 +266,17 @@ collect(fp, smtpmode, hdrp, e)
|
||||
bufferchar:
|
||||
if (!headeronly)
|
||||
e->e_msgsize++;
|
||||
if (mstate == MS_BODY)
|
||||
switch (mstate)
|
||||
{
|
||||
case MS_BODY:
|
||||
/* just put the character out */
|
||||
if (MaxMessageSize <= 0 ||
|
||||
e->e_msgsize <= MaxMessageSize)
|
||||
putc(c, tf);
|
||||
|
||||
/* fall through */
|
||||
|
||||
case MS_DISCARD:
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -298,7 +307,23 @@ collect(fp, smtpmode, hdrp, e)
|
||||
#endif
|
||||
}
|
||||
else if (c != '\0')
|
||||
{
|
||||
*bp++ = c;
|
||||
if (MaxHeaderLineLength > 0 &&
|
||||
++hdrlinelen > MaxHeaderLineLength)
|
||||
{
|
||||
sm_syslog(LOG_NOTICE, e->e_id,
|
||||
"header line too long (%d max) from %s during message collect",
|
||||
MaxHeaderLineLength,
|
||||
CurHostName != NULL ? CurHostName : "localhost");
|
||||
errno = 0;
|
||||
e->e_flags |= EF_CLRQUEUE;
|
||||
e->e_status = "5.6.0";
|
||||
usrerr("552 Header line too long (%d max)",
|
||||
MaxHeaderLineLength);
|
||||
mstate = MS_DISCARD;
|
||||
}
|
||||
}
|
||||
if (istate == IS_BOL)
|
||||
break;
|
||||
}
|
||||
@ -331,6 +356,22 @@ collect(fp, smtpmode, hdrp, e)
|
||||
goto nextstate;
|
||||
}
|
||||
|
||||
if (MaxHeaderLines > 0 &&
|
||||
++nhdrlines > MaxHeaderLines)
|
||||
{
|
||||
sm_syslog(LOG_NOTICE, e->e_id,
|
||||
"too many header lines (%d max) from %s during message collect",
|
||||
MaxHeaderLines,
|
||||
CurHostName != NULL ? CurHostName : "localhost");
|
||||
errno = 0;
|
||||
e->e_flags |= EF_CLRQUEUE;
|
||||
e->e_status = "5.6.0";
|
||||
usrerr("552 Too many header lines (%d max)",
|
||||
MaxHeaderLines);
|
||||
mstate = MS_DISCARD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* check for possible continuation line */
|
||||
do
|
||||
{
|
||||
@ -350,6 +391,7 @@ collect(fp, smtpmode, hdrp, e)
|
||||
if (*--bp != '\n' || *--bp != '\r')
|
||||
bp++;
|
||||
*bp = '\0';
|
||||
|
||||
if (bitset(H_EOH, chompheader(buf, FALSE, hdrp, e)))
|
||||
{
|
||||
mstate = MS_BODY;
|
||||
|
@ -284,6 +284,8 @@ setdefaults(e)
|
||||
ColonOkInAddr = TRUE;
|
||||
DontLockReadFiles = TRUE;
|
||||
DoubleBounceAddr = "postmaster";
|
||||
MaxHeaderLines = MAXHDRLINES;
|
||||
MaxHeaderLineLength = MAXHDRLINELEN;
|
||||
snprintf(buf, sizeof buf, "%s%sdead.letter",
|
||||
_PATH_VARTMP,
|
||||
_PATH_VARTMP[sizeof _PATH_VARTMP - 2] == '/' ? "" : "/");
|
||||
|
@ -69,6 +69,12 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
|
||||
# else
|
||||
# define MAXMACNAMELEN 20 /* max macro name length */
|
||||
# endif
|
||||
# ifndef MAXHDRLINES
|
||||
# define MAXHDRLINES 1000 /* max lines in a message header */
|
||||
# endif
|
||||
# ifndef MAXHDRLINELEN
|
||||
# define MAXHDRLINELEN SMTPLINELIM /* max length of a header line */
|
||||
# endif
|
||||
|
||||
/**********************************************************************
|
||||
** Compilation options.
|
||||
|
@ -1526,6 +1526,10 @@ struct optioninfo
|
||||
#if _FFR_CONTROL_SOCKET
|
||||
#define O_CONTROLSOCKET 0xa9
|
||||
{ "ControlSocketName", O_CONTROLSOCKET, FALSE },
|
||||
#endif
|
||||
#if _FFR_MAX_HEADER_LINES
|
||||
#define O_MAXHDRLINES 0xaa
|
||||
{ "MaxHeaderLines", O_MAXHDRLINES, FALSE },
|
||||
#endif
|
||||
{ NULL, '\0', FALSE }
|
||||
};
|
||||
@ -2466,6 +2470,25 @@ setoption(opt, val, safe, sticky, e)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if _FFR_MAX_HEADER_LINES
|
||||
case O_MAXHDRLINES:
|
||||
p = strchr(val, '/');
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
MaxHeaderLines = atoi(val);
|
||||
if (p != NULL && *p != '\0')
|
||||
MaxHeaderLineLength = atoi(p);
|
||||
|
||||
if (MaxHeaderLines > 0 &&
|
||||
MaxHeaderLines < 50)
|
||||
printf("Warning: MaxHeaderLines: header line limit set lower than 50\n");
|
||||
|
||||
if (MaxHeaderLineLength > 0 &&
|
||||
MaxHeaderLineLength < MAXHDRLINELEN)
|
||||
printf("Warning: MaxHeaderLines: header line length limit set lower than %d\n", MAXHDRLINELEN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
if (tTd(37, 1))
|
||||
{
|
||||
|
@ -1258,6 +1258,8 @@ EXTERN gid_t RunAsGid; /* GID to become for bulk of run */
|
||||
EXTERN int MaxRcptPerMsg; /* max recipients per SMTP message */
|
||||
EXTERN bool DoQueueRun; /* non-interrupt time queue run needed */
|
||||
EXTERN u_long ConnectOnlyTo; /* override connection address (for testing) */
|
||||
EXTERN int MaxHeaderLines; /* max lines of headers per message */
|
||||
EXTERN int MaxHeaderLineLength; /* max length of a header line */
|
||||
#if _FFR_DSN_RRT_OPTION
|
||||
EXTERN bool RrtImpliesDsn; /* turn Return-Receipt-To: into DSN */
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user