home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / bugs / 2bsd / 116 < prev    next >
Encoding:
Text File  |  1993-01-28  |  4.8 KB  |  158 lines

  1. Newsgroups: comp.bugs.2bsd
  2. Path: sparky!uunet!ukma!bogus.sura.net!howland.reston.ans.net!europa.eng.gtefsd.com!wlbr!sms
  3. From: sms@WLV.IIPO.GTEGSC.COM (Steven M. Schultz)
  4. Subject: sendmail stack underflow  + fix (#105)
  5. Message-ID: <1993Jan28.051420.20801@wlbr.iipo.gtegsc.com>
  6. Sender: news@wlbr.iipo.gtegsc.com (news)
  7. Nntp-Posting-Host: wlv.iipo.gtegsc.com
  8. Organization: GTE Government Systems
  9. Date: Thu, 28 Jan 93 05:14:20 GMT
  10. Lines: 146
  11.  
  12. Subject: sendmail stack underflow  + fix (#105)
  13. Index:    usr.lib/sendmail/src/daemon.c 2.11BSD
  14.  
  15. Description:
  16.     When 'sendmail' is linked with the resolver(5) routines there
  17.     is a flow of execution which causes the stack pointer (sp) to
  18.     be decremented into an invalid region in the adjacent data space.
  19.  
  20. Repeat-By:
  21.     Difficult to repeat because much depends on exactly how large
  22.     sendmail's D space is (if there is room to expand the stack
  23.     the problem will not occur), how complex the sendmail.cf file
  24.     is, etc.  If your sendmail periodically dumps core and the
  25.     stack trace looks something like this then you're experiencing
  26.     the problem and this fix will help.  All numbers are octal, the
  27.     number at the left is the current stack pointer value and the
  28.     actual arguments are not given.  The 'sp' value at the time
  29.     sendmail crashed was 157556:
  30.  
  31.     160646 _res_sen(...)
  32.     162676 _rs_qry(...)
  33.     163732 _rs_qryd(...)
  34.     163776 _res_sea(...)
  35.     166020 _gethbyn(...)
  36.     166444 _maphost(...)
  37.     167712 _rewrite(...)
  38.     170444 _remoten(...)
  39.     171416 _commaiz(...)
  40.     174052 L162(...) - not sure why this came out with a local name...
  41.     174052 _smtpdat(...)
  42.     175154 _deliver(...)
  43.     175406 _sendall(...)
  44.     176402 _smtp(...)
  45.     177402 _main()
  46.  
  47.     How does 'sp' get pushed into the data segment and why does it
  48.     cause a crash of sendmail?  The data segment has expanded into
  49.     into seg6 (virtual range 140000-157776) but the entire 8kb has 
  50.     not been allocated, for example the last valid data address 
  51.     might be 155000 - the gap between end of data and 160000 is a
  52.     "noman's land"
  53.  
  54.     In res_send (one of the resolver routines) the stack pointer
  55.     is 160646 and res_send allocates (yet another) 512 byte buffer
  56.     (plus a couple more local variables) on the stack which causes 'sp' 
  57.     to be decremented to 157646.  This is above the last valid
  58.     data address (155000) and below 160000 (last allocated stack
  59.     space), thus the first reference to where sp points will cause
  60.     a fault.
  61.  
  62.     Sendmail's habit of allocating 512 and 1kb buffers at almost
  63.     every level of function call is the main culprit (the resolver
  64.     routines are almost as bad).
  65.  
  66. Fix:
  67.     The fix below reduces sendmail's stack requirement by 256 bytes
  68.     which has proven to be sufficient to prevent the program from
  69.     crashing.  Not sure why the address string was copied when earlier
  70.     references to bracketed dotted quads were handled by simply
  71.     poking a zero into the string and restoring it after 'inet_addr'
  72.     was finished.
  73.  
  74. ==========================cut here=============================
  75. *** /usr/src/usr.lib/sendmail/src/daemon.c.old    Wed Feb 10 15:26:12 1988
  76. --- /usr/src/usr.lib/sendmail/src/daemon.c    Wed Jan 27 20:26:37 1993
  77. ***************
  78. *** 14,20 ****
  79.   
  80.   # ifndef DAEMON
  81.   #if !defined(lint) && !defined(NOSCCS)
  82. ! static char    SccsId[] = "@(#)daemon.c    5.19 (Berkeley) 5/6/86    (w/o daemon mode)";
  83.   # endif
  84.   # else
  85.   
  86. --- 14,20 ----
  87.   
  88.   # ifndef DAEMON
  89.   #if !defined(lint) && !defined(NOSCCS)
  90. ! static char    SccsId[] = "@(#)daemon.c    5.20 (2.11BSD) 1/26/93    (w/o daemon mode)";
  91.   # endif
  92.   # else
  93.   
  94. ***************
  95. *** 25,31 ****
  96.   # include <sys/resource.h>
  97.   
  98.   #if !defined(lint) && !defined(NOSCCS)
  99. ! static char    SccsId[] = "@(#)daemon.c    5.19 (Berkeley) 5/6/86 (with daemon mode)";
  100.   # endif
  101.   
  102.   /*
  103. --- 25,31 ----
  104.   # include <sys/resource.h>
  105.   
  106.   #if !defined(lint) && !defined(NOSCCS)
  107. ! static char    SccsId[] = "@(#)daemon.c    5.20 (2.11BSD) 1/26/93 (with daemon mode)";
  108.   # endif
  109.   
  110.   /*
  111. ***************
  112. *** 499,507 ****
  113.   
  114.       /*
  115.       **  If first character is a bracket, then it is an address
  116. !     **  lookup.  Address is copied into a temporary buffer to
  117. !     **  strip the brackets and to preserve hbuf if address is
  118. !     **  unknown.
  119.       */
  120.   
  121.       if (*hbuf == '[')
  122. --- 499,505 ----
  123.   
  124.       /*
  125.       **  If first character is a bracket, then it is an address
  126. !     **  lookup.
  127.       */
  128.   
  129.       if (*hbuf == '[')
  130. ***************
  131. *** 508,520 ****
  132.       {
  133.           extern struct hostent *gethostbyaddr();
  134.           u_long in_addr;
  135. !         char ptr[256];
  136. !         char *bptr;
  137.   
  138. !         (void) strcpy(ptr, hbuf);
  139. !         bptr = index(ptr,']');
  140.           *bptr = '\0';
  141. !         in_addr = inet_addr(&ptr[1]);
  142.           hp = gethostbyaddr((char *) &in_addr, sizeof(struct in_addr), AF_INET);
  143.           if (hp == NULL)
  144.               return;
  145. --- 506,517 ----
  146.       {
  147.           extern struct hostent *gethostbyaddr();
  148.           u_long in_addr;
  149. !         register char *bptr;
  150.   
  151. !         bptr = index(hbuf,']');
  152.           *bptr = '\0';
  153. !         in_addr = inet_addr(&hbuf[1]);
  154. !         *bptr = ']';
  155.           hp = gethostbyaddr((char *) &in_addr, sizeof(struct in_addr), AF_INET);
  156.           if (hp == NULL)
  157.               return;
  158.