home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.bugs.2bsd
- Path: sparky!uunet!ukma!bogus.sura.net!howland.reston.ans.net!europa.eng.gtefsd.com!wlbr!sms
- From: sms@WLV.IIPO.GTEGSC.COM (Steven M. Schultz)
- Subject: sendmail stack underflow + fix (#105)
- Message-ID: <1993Jan28.051420.20801@wlbr.iipo.gtegsc.com>
- Sender: news@wlbr.iipo.gtegsc.com (news)
- Nntp-Posting-Host: wlv.iipo.gtegsc.com
- Organization: GTE Government Systems
- Date: Thu, 28 Jan 93 05:14:20 GMT
- Lines: 146
-
- Subject: sendmail stack underflow + fix (#105)
- Index: usr.lib/sendmail/src/daemon.c 2.11BSD
-
- Description:
- When 'sendmail' is linked with the resolver(5) routines there
- is a flow of execution which causes the stack pointer (sp) to
- be decremented into an invalid region in the adjacent data space.
-
- Repeat-By:
- Difficult to repeat because much depends on exactly how large
- sendmail's D space is (if there is room to expand the stack
- the problem will not occur), how complex the sendmail.cf file
- is, etc. If your sendmail periodically dumps core and the
- stack trace looks something like this then you're experiencing
- the problem and this fix will help. All numbers are octal, the
- number at the left is the current stack pointer value and the
- actual arguments are not given. The 'sp' value at the time
- sendmail crashed was 157556:
-
- 160646 _res_sen(...)
- 162676 _rs_qry(...)
- 163732 _rs_qryd(...)
- 163776 _res_sea(...)
- 166020 _gethbyn(...)
- 166444 _maphost(...)
- 167712 _rewrite(...)
- 170444 _remoten(...)
- 171416 _commaiz(...)
- 174052 L162(...) - not sure why this came out with a local name...
- 174052 _smtpdat(...)
- 175154 _deliver(...)
- 175406 _sendall(...)
- 176402 _smtp(...)
- 177402 _main()
-
- How does 'sp' get pushed into the data segment and why does it
- cause a crash of sendmail? The data segment has expanded into
- into seg6 (virtual range 140000-157776) but the entire 8kb has
- not been allocated, for example the last valid data address
- might be 155000 - the gap between end of data and 160000 is a
- "noman's land"
-
- In res_send (one of the resolver routines) the stack pointer
- is 160646 and res_send allocates (yet another) 512 byte buffer
- (plus a couple more local variables) on the stack which causes 'sp'
- to be decremented to 157646. This is above the last valid
- data address (155000) and below 160000 (last allocated stack
- space), thus the first reference to where sp points will cause
- a fault.
-
- Sendmail's habit of allocating 512 and 1kb buffers at almost
- every level of function call is the main culprit (the resolver
- routines are almost as bad).
-
- Fix:
- The fix below reduces sendmail's stack requirement by 256 bytes
- which has proven to be sufficient to prevent the program from
- crashing. Not sure why the address string was copied when earlier
- references to bracketed dotted quads were handled by simply
- poking a zero into the string and restoring it after 'inet_addr'
- was finished.
-
- ==========================cut here=============================
- *** /usr/src/usr.lib/sendmail/src/daemon.c.old Wed Feb 10 15:26:12 1988
- --- /usr/src/usr.lib/sendmail/src/daemon.c Wed Jan 27 20:26:37 1993
- ***************
- *** 14,20 ****
-
- # ifndef DAEMON
- #if !defined(lint) && !defined(NOSCCS)
- ! static char SccsId[] = "@(#)daemon.c 5.19 (Berkeley) 5/6/86 (w/o daemon mode)";
- # endif
- # else
-
- --- 14,20 ----
-
- # ifndef DAEMON
- #if !defined(lint) && !defined(NOSCCS)
- ! static char SccsId[] = "@(#)daemon.c 5.20 (2.11BSD) 1/26/93 (w/o daemon mode)";
- # endif
- # else
-
- ***************
- *** 25,31 ****
- # include <sys/resource.h>
-
- #if !defined(lint) && !defined(NOSCCS)
- ! static char SccsId[] = "@(#)daemon.c 5.19 (Berkeley) 5/6/86 (with daemon mode)";
- # endif
-
- /*
- --- 25,31 ----
- # include <sys/resource.h>
-
- #if !defined(lint) && !defined(NOSCCS)
- ! static char SccsId[] = "@(#)daemon.c 5.20 (2.11BSD) 1/26/93 (with daemon mode)";
- # endif
-
- /*
- ***************
- *** 499,507 ****
-
- /*
- ** If first character is a bracket, then it is an address
- ! ** lookup. Address is copied into a temporary buffer to
- ! ** strip the brackets and to preserve hbuf if address is
- ! ** unknown.
- */
-
- if (*hbuf == '[')
- --- 499,505 ----
-
- /*
- ** If first character is a bracket, then it is an address
- ! ** lookup.
- */
-
- if (*hbuf == '[')
- ***************
- *** 508,520 ****
- {
- extern struct hostent *gethostbyaddr();
- u_long in_addr;
- ! char ptr[256];
- ! char *bptr;
-
- ! (void) strcpy(ptr, hbuf);
- ! bptr = index(ptr,']');
- *bptr = '\0';
- ! in_addr = inet_addr(&ptr[1]);
- hp = gethostbyaddr((char *) &in_addr, sizeof(struct in_addr), AF_INET);
- if (hp == NULL)
- return;
- --- 506,517 ----
- {
- extern struct hostent *gethostbyaddr();
- u_long in_addr;
- ! register char *bptr;
-
- ! bptr = index(hbuf,']');
- *bptr = '\0';
- ! in_addr = inet_addr(&hbuf[1]);
- ! *bptr = ']';
- hp = gethostbyaddr((char *) &in_addr, sizeof(struct in_addr), AF_INET);
- if (hp == NULL)
- return;
-