diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2006-06-14 17:53:03 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2006-06-14 17:53:03 +0000 |
commit | f9a4ca8c02838136b15b3df1e5077afeec9a712b (patch) | |
tree | f50f5c2fb6cd1158f9aec5a406b81c69d04827b8 /gnu/usr.sbin/sendmail | |
parent | 9330edf9121f61eccafacb7d9438c6c84c598fb6 (diff) |
fix bug which would make very deeply nested mime cause (essentially)
a stack overflow and thus make sendmail queue processing crash. not
really exploitable to gain anything except denial of service. vu#146718
Diffstat (limited to 'gnu/usr.sbin/sendmail')
-rw-r--r-- | gnu/usr.sbin/sendmail/sendmail/deliver.c | 4 | ||||
-rw-r--r-- | gnu/usr.sbin/sendmail/sendmail/mime.c | 36 | ||||
-rw-r--r-- | gnu/usr.sbin/sendmail/sendmail/sendmail.h | 3 |
3 files changed, 33 insertions, 10 deletions
diff --git a/gnu/usr.sbin/sendmail/sendmail/deliver.c b/gnu/usr.sbin/sendmail/sendmail/deliver.c index fd4ffd35b10..5711f2d5dbf 100644 --- a/gnu/usr.sbin/sendmail/sendmail/deliver.c +++ b/gnu/usr.sbin/sendmail/sendmail/deliver.c @@ -4623,7 +4623,7 @@ putbody(mci, e, separator) /* now do the hard work */ boundaries[0] = NULL; mci->mci_flags |= MCIF_INHEADER; - if (mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER) == + if (mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER, 0) == SM_IO_EOF) goto writeerr; } @@ -4654,7 +4654,7 @@ putbody(mci, e, separator) SuprErrs = true; if (mime8to7(mci, e->e_header, e, boundaries, - M87F_OUTER|M87F_NO8TO7) == SM_IO_EOF) + M87F_OUTER|M87F_NO8TO7, 0) == SM_IO_EOF) goto writeerr; /* restore SuprErrs */ diff --git a/gnu/usr.sbin/sendmail/sendmail/mime.c b/gnu/usr.sbin/sendmail/sendmail/mime.c index 97cc8f5c053..b16dc888ecf 100644 --- a/gnu/usr.sbin/sendmail/sendmail/mime.c +++ b/gnu/usr.sbin/sendmail/sendmail/mime.c @@ -80,6 +80,7 @@ static bool MapNLtoCRLF; ** boundaries -- the currently pending message boundaries. ** NULL if we are processing the outer portion. ** flags -- to tweak processing. +** level -- recursion level. ** ** Returns: ** An indicator of what terminated the message part: @@ -96,12 +97,13 @@ struct args }; int -mime8to7(mci, header, e, boundaries, flags) +mime8to7(mci, header, e, boundaries, flags, level) register MCI *mci; HDR *header; register ENVELOPE *e; char **boundaries; int flags; + int level; { register char *p; int linelen; @@ -122,6 +124,18 @@ mime8to7(mci, header, e, boundaries, flags) char pvpbuf[MAXLINE]; extern unsigned char MimeTokenTab[256]; + if (level > MAXMIMENESTING) + { + if (!bitset(EF_TOODEEP, e->e_flags)) + { + if (tTd(43, 4)) + sm_dprintf("mime8to7: too deep, level=%d\n", + level); + usrerr("mime8to7: recursion level %d exceeded", + level); + e->e_flags |= EF_DONT_MIME|EF_TOODEEP; + } + } if (tTd(43, 1)) { sm_dprintf("mime8to7: flags = %x, boundaries =", flags); @@ -242,7 +256,9 @@ mime8to7(mci, header, e, boundaries, flags) */ if (sm_strcasecmp(type, "multipart") == 0 && - (!bitset(M87F_NO8BIT, flags) || bitset(M87F_NO8TO7, flags))) + (!bitset(M87F_NO8BIT, flags) || bitset(M87F_NO8TO7, flags)) && + !bitset(EF_TOODEEP, e->e_flags) + ) { if (sm_strcasecmp(subtype, "digest") == 0) @@ -286,10 +302,13 @@ mime8to7(mci, header, e, boundaries, flags) } if (i >= MAXMIMENESTING) { - usrerr("mime8to7: multipart nesting boundary too deep"); + if (tTd(43, 4)) + sm_dprintf("mime8to7: too deep, i=%d\n", i); + if (!bitset(EF_TOODEEP, e->e_flags)) + usrerr("mime8to7: multipart nesting boundary too deep"); /* avoid bounce loops */ - e->e_flags |= EF_DONT_MIME; + e->e_flags |= EF_DONT_MIME|EF_TOODEEP; } else { @@ -333,7 +352,8 @@ mime8to7(mci, header, e, boundaries, flags) goto writeerr; if (tTd(43, 101)) putline("+++after putheader", mci); - bt = mime8to7(mci, hdr, e, boundaries, flags); + bt = mime8to7(mci, hdr, e, boundaries, flags, + level + 1); if (bt == SM_IO_EOF) goto writeerr; } @@ -374,7 +394,8 @@ mime8to7(mci, header, e, boundaries, flags) if (sm_strcasecmp(type, "message") == 0) { - if (!wordinclass(subtype, 's')) + if (!wordinclass(subtype, 's') || + bitset(EF_TOODEEP, e->e_flags)) { flags |= M87F_NO8BIT; } @@ -397,7 +418,8 @@ mime8to7(mci, header, e, boundaries, flags) !bitset(M87F_NO8TO7, flags) && !putline("MIME-Version: 1.0", mci)) goto writeerr; - bt = mime8to7(mci, hdr, e, boundaries, flags); + bt = mime8to7(mci, hdr, e, boundaries, flags, + level + 1); mci->mci_flags &= ~MCIF_INMIME; return bt; } diff --git a/gnu/usr.sbin/sendmail/sendmail/sendmail.h b/gnu/usr.sbin/sendmail/sendmail/sendmail.h index 88b71b7b969..a0ddc182f5f 100644 --- a/gnu/usr.sbin/sendmail/sendmail/sendmail.h +++ b/gnu/usr.sbin/sendmail/sendmail/sendmail.h @@ -942,6 +942,7 @@ struct envelope #define EF_TOOBIG 0x02000000L /* message is too big */ #define EF_SPLIT 0x04000000L /* envelope has been split */ #define EF_UNSAFE 0x08000000L /* unsafe: read from untrusted source */ +#define EF_TOODEEP 0x10000000L /* message is nested too deep */ #define DLVR_NOTIFY 0x01 #define DLVR_RETURN 0x02 @@ -1655,7 +1656,7 @@ EXTERN unsigned long PrivacyFlags; /* privacy flags */ /* functions */ extern bool mime7to8 __P((MCI *, HDR *, ENVELOPE *)); -extern int mime8to7 __P((MCI *, HDR *, ENVELOPE *, char **, int)); +extern int mime8to7 __P((MCI *, HDR *, ENVELOPE *, char **, int, int)); /* ** Flags passed to returntosender. |