Thread View: comp.bugs.2bsd
1 messages
1 total messages
Started by Steven M. Schultz
Thu, 28 Jan 1993 05:14
sendmail stack underflow + fix (#105)
Author: Steven M. Schultz
Date: Thu, 28 Jan 1993 05:14
Date: Thu, 28 Jan 1993 05:14
146 lines
5095 bytes
5095 bytes
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;
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads