sendmail aborts with longjmp botch
Chris Torek
chris at mimsy.UUCP
Wed Mar 9 21:14:28 AEST 1988
Index: /usr/src/usr.lib/sendmail/src/usersmtp.c 4.3BSD Fix
Description:
When processing long mailing lists, sendmail sometimes
aborts with a `longjmp botch'.
Repeat-by:
Difficult.
Fix:
The problem occurs when sendmail has a read timeout of more
than five minutes specified in the configuration file. In
usersmtp.c, sendmail sets up a timeout event around the
`greeting' reply call; this timeout is scheduled to occur in
300 seconds (5 minutes). It then calls reply(), which calls
sfgets(), which notes that ReadTimeout is (e.g.) 1 hour.
sfgets sets another timeout event for one hour, reads a line,
clears the timeout event, and returns to usersmtp, which clears
its own read timeout.
Suppose, however, that no reply is made within the first five
minutes. Then the first event, usersmtp.c's timeout, fires
off. This does a longjmp() all the way out of sfgets and reply
back to usersmtp.c, which then returns to its caller, leaving
in the event queue the event posted by sfgets. In one hour, if
sendmail is still running by then, this event attempts to
longjmp back to the context set by the sfgets from reply. This
context is long gone and, with any luck, longjmp notices and
aborts.
There are several ways to fix this. The most general would be
for sendmail to have a `wrapper' around setjmp and longjmp that
would provide unwind protection. That is beyond the scope of
this message.
The second way is simply to remove the 5 minute timeout from
usersmtp.c. Commenting out the setevent() call should
suffice. This is somewhat undesirable but is by far the
easiest fix.
The third way is to have usersmtp.c arrange for ReadTimeout to
be set to 300, preserving its old value and restoring it after
the first call to reply. The following UNTESTED change does
this.
Chris
*** usersmtp.c.old Wed Mar 9 06:08:59 1988
--- usersmtp.c Wed Mar 9 06:10:53 1988
***************
*** 67,72 ****
*/
- jmp_buf CtxGreeting;
-
smtpinit(m, pvp)
struct mailer *m;
--- 67,70 ----
***************
*** 76,80 ****
EVENT *gte;
char buf[MAXNAME];
! extern greettimeout();
/*
--- 74,78 ----
EVENT *gte;
char buf[MAXNAME];
! int oldtimeout;
/*
***************
*** 129,138 ****
*/
! if (setjmp(CtxGreeting) != 0)
! goto tempfail;
! gte = setevent((time_t) 300, greettimeout, 0);
SmtpPhase = "greeting wait";
r = reply(m);
! clrevent(gte);
if (r < 0 || REPLYTYPE(r) != 2)
goto tempfail;
--- 127,135 ----
*/
! oldtimeout = ReadTimeout;
! ReadTimeout = 5 * 60;
SmtpPhase = "greeting wait";
r = reply(m);
! ReadTimeout = oldtimeout;
if (r < 0 || REPLYTYPE(r) != 2)
goto tempfail;
***************
*** 213,223 ****
}
-
- static
- greettimeout()
- {
- /* timeout reading the greeting message */
- longjmp(CtxGreeting, 1);
- }
/*
** SMTPRCPT -- designate recipient.
--- 210,213 ----
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at mimsy.umd.edu Path: uunet!mimsy!chris
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list