"Fossies" - the Fresh Open Source Software Archive

Member "libsafe-2.0-16/src/util.c" (30 May 2002, 44039 Bytes) of package /linux/misc/old/libsafe-2.0-16.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #ident "$Name: release2_0-16 $"
    2 #ident "$Id: util.c,v 1.58 2002/05/30 14:44:38 ttsai Exp $"
    3 
    4 /*
    5  * Copyright (C) 2002 Avaya Labs, Avaya Inc.
    6  * Copyright (C) 1999 Bell Labs, Lucent Technologies.
    7  * Copyright (C) Arash Baratloo, Timothy Tsai, and Navjot Singh.
    8  *
    9  * This file is part of the Libsafe library.
   10  * Libsafe version 2.x: protecting against stack smashing attacks.
   11  *
   12  * This library is free software; you can redistribute it and/or
   13  * modify it under the terms of the GNU Lesser General Public
   14  * License as published by the Free Software Foundation; either
   15  * version 2.1 of the License, or (at your option) any later version.
   16  *
   17  * This library is distributed in the hope that it will be useful,
   18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   20  * Lesser General Public License for more details.
   21  *
   22  * You should have received a copy of the GNU Lesser General Public
   23  * License along with this library; if not, write to the Free Software
   24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   25  *
   26  * For more information, 
   27  *   visit http://www.research.avayalabs.com/project/libsafe/index.html
   28  *   or email libsafe@research.avayalabs.com
   29  */
   30 
   31 
   32 #include <unistd.h>     /* defines readlink() */
   33 #include <syslog.h>     /* defines syslog(3) */
   34 #include <stdarg.h>     /* defines va_args */
   35 #include <signal.h>     /* defines kill() */
   36 #include <stdio.h>
   37 #include <unistd.h>             /* defines pipe() */
   38 #include <sys/resource.h>   /* defines RLIM_INFINITY */
   39 #include <stdlib.h>
   40 #include <sys/socket.h>
   41 #include "util.h"
   42 #include "log.h"
   43 
   44 #define __USE_GNU       /* defines strnlen() */
   45 #include <string.h>
   46 
   47 // Sometimes environ is defined in unistd.h.  If so, then comment out the
   48 // following declaration.
   49 extern char **environ[];
   50 
   51 
   52 /*****************************************************************************
   53  *
   54  * Miscellaneous functions.
   55  *
   56  *****************************************************************************/
   57 
   58 static char *get_exename(char *exename, int size) {
   59     int res;
   60     
   61     /*
   62      * get the name of the current executable
   63      */
   64     if ((res = readlink("/proc/self/exe", exename, size - 1)) == -1)
   65     exename[0] = '\0';
   66     else
   67     exename[res] = '\0';
   68     return (exename);
   69 }
   70 
   71 
   72 /*
   73  * Has _libsafe_die() been called?
   74  */
   75 static int dying = 0;
   76 
   77 
   78 /*
   79  * Have we detected a stack with no frame pointers?  If so, we will assume that
   80  * we can bypass the libsafe checks for the entire process from that point on.
   81  */
   82 extern int _libsafe_exclude;
   83 
   84 
   85 #define PTHREAD_STACK_SIZE  (0x1fffff)
   86 /*
   87  * Return the highest memory address associated with this addr.  This is just
   88  * a guess.  We assume that the main thread stack starts at 0xc0000000 and is
   89  * 8MB.  The other threads start at 0xbf800000 (immediately after the 8MB space
   90  * for the main thread stack) and are all 2MB.
   91  */
   92 #define find_stack_start(addr)                          \
   93      /* Past stack area */                          \
   94     ((addr > (void*)0xc0000000) ? NULL :                    \
   95                                         \
   96      /* Main thread stack */                            \
   97      (addr > (void*)0xbf800000) ? (void*)0xc0000000 :               \
   98                                         \
   99      /* Other thread stacks */                          \
  100     ((void*)(((uint)addr & (~PTHREAD_STACK_SIZE)) + PTHREAD_STACK_SIZE))\
  101                                         \
  102     )
  103 
  104 
  105 /*****************************************************************************
  106  * 
  107  * These are functions that do the real work of determining if a libsafe
  108  * violation has occurred.
  109  *
  110  *****************************************************************************/
  111 
  112 /* Given an address 'addr' returns 0 iff the address does not point to a stack
  113  * variable.  Otherwise, it returns a positive number indicating the number of
  114  * bytes (distance) between the 'addr' and the frame pointer it resides in.
  115  * Note: stack grows down, and arrays/structures grow up.
  116  */
  117 uint _libsafe_stackVariableP(void *addr) {
  118     /*
  119      * bufsize is the distance between addr and the end of the stack frame.
  120      * It's what _libsafe_stackVariableP() is trying to calculate.
  121      */
  122     uint bufsize = 0;
  123 
  124     /*
  125      * (Vandoorselaere Yoann)
  126      * We have now just one cast.
  127      */
  128     void *fp, *sp;
  129     
  130     /*
  131      * nextfp is used in the check for -fomit-frame-pointer code.
  132      */
  133     void *nextfp;
  134 
  135     /*
  136      * stack_start is the highest address in the memory space mapped for this
  137      * stack.
  138      */
  139     void *stack_start;
  140 
  141     /*
  142      * If _libsafe_die() has been called, then we don't need to do anymore
  143      * libsafe checking.
  144      */
  145     if (dying)
  146     return 0;
  147 
  148     /*
  149      * (Arash Baratloo / Yoann Vandoorselaere)
  150      * use the stack address of the first declared variable to get the 'sp'
  151      * address in a portable way.
  152      */
  153     sp = &fp;
  154 
  155     /*
  156      * Stack grows downwards (toward 0x00).  Thus, if the stack pointer is
  157      * above (>) 'addr', 'addr' can't be on the stack.
  158      */
  159     if (sp > addr)
  160     return 0;
  161 
  162     /*
  163      * Note: the program name is always stored at 0xbffffffb (documented in the
  164      * book Linux Kernel).  Search back through the frames to find the frame
  165      * containing 'addr'.
  166      */
  167     fp = __builtin_frame_address(0);
  168 
  169     /*
  170      * Note that find_stack_start(fp) should never return NULL, since fp is
  171      * always guaranteed to be on the stack.
  172      */
  173     stack_start = find_stack_start((void*)&fp);
  174 
  175     while ((sp < fp) && (fp <= stack_start)) {
  176     if (fp > addr) {
  177         /*
  178          * found the frame -- now check the rest of the stack
  179          */
  180         bufsize = fp - addr;
  181         break;
  182     }
  183 
  184     nextfp = *(void **) fp;
  185 
  186     /*
  187      * The following checks are meant to detect code that doesn't insert
  188      * frame pointers onto the stack.  (i.e., code that is compiled with
  189      * -fomit-frame-pointer).
  190      */
  191 
  192     /*
  193      * Make sure frame pointers are word aligned.
  194      */
  195     if ((uint)nextfp & 0x03) {
  196         LOG(2, "fp not word aligned; bypass enabled\n");
  197         _libsafe_exclude = 1;
  198         return 0;
  199     }
  200 
  201     /*
  202      * Make sure frame pointers are monotonically increasing.
  203      */
  204     if (nextfp <= fp) {
  205         LOG(2, "fp not monotonically increasing; bypass enabled\n");
  206         _libsafe_exclude = 1;
  207         return 0;
  208     }
  209 
  210     fp = nextfp;
  211     }
  212 
  213     /*
  214      * If we haven't found the correct frame by now, it either means that addr
  215      * isn't on the stack or that the stack doesn't contain frame pointers.
  216      * Either way, we will return 0 to bypass checks for addr.
  217      */
  218     if (bufsize == 0) {
  219     return 0;
  220     }
  221 
  222     /*
  223      * Now check to make sure that the rest of the stack looks reasonable.
  224      */
  225     while ((sp < fp) && (fp <= stack_start)) {
  226     nextfp = *(void **) fp;
  227 
  228     if (nextfp == NULL) {
  229         /*
  230          * This is the only correct way to end the stack.
  231          */
  232         return bufsize;
  233     }
  234 
  235     /*
  236      * Make sure frame pointers are word aligned.
  237      */
  238     if ((uint)nextfp & 0x03) {
  239         LOG(2, "fp not word aligned; bypass enabled\n");
  240         _libsafe_exclude = 1;
  241         return 0;
  242     }
  243 
  244     /*
  245      * Make sure frame pointers are monotonically * increasing.
  246      */
  247     if (nextfp <= fp) {
  248         LOG(2, "fp not monotonically increasing; bypass enabled\n");
  249         _libsafe_exclude = 1;
  250         return 0;
  251     }
  252 
  253     fp = nextfp;
  254     }
  255 
  256     /*
  257      * We weren't able to say for sure that the stack contains valid frame
  258      * pointers, so we will return 0, which means that no check for addr will
  259      * be done.
  260      */
  261     return 0;
  262 }
  263 
  264 
  265 /*
  266  * Save the return addresses and frame pointers into ra_array and fp_array.
  267  * Place the number of stack frames traversed into count.  Save at most
  268  * maxcount values into either ra_array or fp_array.  If maxcount is exceeded
  269  * (ie, ra_array[] and fp_array[] are too small) or the full set of values is
  270  * not stored, return -1; else return the count of items stores in ra_array or
  271  * fp_array.
  272  */
  273 int _libsafe_save_ra_fp(int maxcount, caddr_t *ra_array, caddr_t *fp_array) {
  274     /*
  275      * How many values we have placed in ra[] or fp[].
  276      */
  277     int count = 0;
  278 
  279     /*
  280      * We will use these pointers to iterate through ra_array[] and fp_array[],
  281      * because that will be faster than using ra_array[index] notation.
  282      */
  283     caddr_t *ra_p = ra_array;
  284     caddr_t *fp_p = fp_array;
  285 
  286     /*
  287      * (Vandoorselaere Yoann)
  288      * We have now just one cast.
  289      */
  290     void *fp, *sp;
  291     
  292     /*
  293      * nextfp is used in the check for -fomit-frame-pointer code.
  294      */
  295     void *nextfp;
  296 
  297     /*
  298      * stack_start is the highest address in the memory space mapped for this
  299      * stack.
  300      */
  301     void *stack_start;
  302 
  303     /*
  304      * If _libsafe_die() has been called, then we don't need to do anymore
  305      * libsafe checking.
  306      */
  307     if (dying)
  308     return -1;
  309 
  310     /*
  311      * (Arash Baratloo / Yoann Vandoorselaere)
  312      * use the stack address of the first declared variable to get the 'sp'
  313      * address in a portable way.
  314      */
  315     sp = &fp;
  316 
  317     /*
  318      * We start saving at not this stack frame but the stack frame of the
  319      * function that called this function.
  320      */
  321     fp = __builtin_frame_address(1);
  322 
  323     /*
  324      * If fp <= sp, this means that we're not looking at the correct stack.
  325      */
  326     if (fp <= sp)
  327     return -1;
  328 
  329     /*
  330      * Note that find_stack_start(fp) should never return NULL, since fp is
  331      * always guaranteed to be on the stack.
  332      */
  333     stack_start = find_stack_start((void*)&fp);
  334 
  335     /*
  336      * Since we check to see if fp is monotonically increasing inside the while
  337      * loop, we don't need to check for it in the while predicate.
  338      */
  339     while ((fp <= stack_start)) {
  340     /*
  341      * Make sure there's still enough space in ra[] and fp[] to store the
  342      * values for the current stack frame.
  343      */
  344     if (count+1 >= maxcount) {
  345         return -1;
  346     }
  347 
  348     /*
  349      * Store the current return address and frame pointer.  The return
  350      * address will be the word immediately after the frame pointer.
  351      */
  352     /*
  353     ra_array[count] = *(caddr_t*)(fp+sizeof(void*));
  354     fp_array[count++] = fp;
  355     */
  356 
  357 
  358 
  359     *ra_p++ = *(caddr_t*)(fp+sizeof(void*));
  360     *fp_p++ = fp;
  361     count++;
  362 
  363 
  364 
  365 
  366 
  367     nextfp = *(void **) fp;
  368 
  369     if (nextfp == NULL) {
  370         /*
  371          * This is the only correct way to end the stack.
  372          */
  373         return count;
  374     }
  375 
  376     /*
  377      * Make sure frame pointers are word aligned.
  378      */
  379     if ((uint)nextfp & 0x03) {
  380         LOG(2, "fp not word aligned; bypass enabled\n");
  381         _libsafe_exclude = 1;
  382         return -1;
  383     }
  384 
  385     /*
  386      * Make sure frame pointers are monotonically * increasing.
  387      */
  388     if (nextfp <= fp) {
  389         LOG(2, "fp not monotonically increasing; bypass enabled\n");
  390         _libsafe_exclude = 1;
  391         return -1;
  392     }
  393 
  394     fp = nextfp;
  395     }
  396 
  397     /*
  398      * We weren't able to say for sure that the stack contains valid frame
  399      * pointers, so we will return -1.
  400      */
  401     return -1;
  402 }
  403 
  404 
  405 /*
  406  * Make sure that the current return addresses and frame pointers on the stack
  407  * match the values saved in ra_array and fp_array.  Return 0 if all values
  408  * match; or return 1 if the check was not completed; else return -1 if the
  409  * check was completed and failed.  count is the number of valid values in
  410  * ra_array and fp_array.
  411  *
  412  * Note that _libsafe_save_ra_fp() and _libsafe_verify_ra_fp() must be called
  413  * from within the same stack frame.
  414  */
  415 int _libsafe_verify_ra_fp(int maxcount, caddr_t *ra_array, caddr_t *fp_array) {
  416     /*
  417      * Which stack frame are we currently looking at?
  418      */
  419     int count = 0;
  420 
  421     /*
  422      * We will use these pointers to iterate through ra_array[] and fp_array[],
  423      * because that will be faster than using ra_array[index] notation.
  424      */
  425     caddr_t *ra_p = ra_array;
  426     caddr_t *fp_p = fp_array;
  427 
  428     /*
  429      * (Vandoorselaere Yoann)
  430      * We have now just one cast.
  431      */
  432     void *fp, *sp;
  433     
  434     /*
  435      * nextfp is used in the check for -fomit-frame-pointer code.
  436      */
  437     void *nextfp;
  438 
  439     /*
  440      * stack_start is the highest address in the memory space mapped for this
  441      * stack.
  442      */
  443     void *stack_start;
  444 
  445     /*
  446      * If _libsafe_die() has been called, then we don't need to do anymore
  447      * libsafe checking.
  448      */
  449     if (dying)
  450     return 1;
  451 
  452     /*
  453      * (Arash Baratloo / Yoann Vandoorselaere)
  454      * use the stack address of the first declared variable to get the 'sp'
  455      * address in a portable way.
  456      */
  457     sp = &fp;
  458 
  459     /*
  460      * We start saving at not this stack frame but the stack frame of the
  461      * function that called this function.
  462      */
  463     fp = __builtin_frame_address(1);
  464 
  465     /*
  466      * If fp <= sp, this means that we're not looking at the correct stack.
  467      */
  468     if (fp <= sp)
  469     return -1;
  470 
  471     /*
  472      * Note that find_stack_start(fp) should never return NULL, since fp is
  473      * always guaranteed to be on the stack.
  474      */
  475     stack_start = find_stack_start((void*)&fp);
  476 
  477     while ((fp <= stack_start)) {
  478     /*
  479      * Store the current return address and frame pointer.  The return
  480      * address will be the word immediately after the frame pointer.
  481      */
  482     /*
  483     if (ra_array[count] != *(caddr_t*)(fp+sizeof(void*)) ||
  484         fp_array[count] != fp ||
  485         count++ > maxcount)
  486     */
  487     if (*ra_p++ != *(caddr_t*)(fp+sizeof(void*)) ||
  488         *fp_p++ != fp ||
  489         count++ > maxcount)
  490     {
  491         /*
  492          * Mismatch found!
  493          */
  494 
  495         /*
  496          * In order to print out the true call stack, we need to restore
  497          * the correct return addresses and frame pointers to the stack.
  498          */
  499         for (; count<maxcount; count++) {
  500         *(caddr_t*)(fp+sizeof(void*)) = ra_array[count];
  501         *(caddr_t*)fp = fp_array[count];
  502         }
  503 
  504         return -1;
  505     }
  506 
  507     nextfp = *(void **) fp;
  508 
  509     if (nextfp == NULL) {
  510         /*
  511          * This is the only correct way to end the stack.
  512          */
  513         return 0;
  514     }
  515 
  516     /*
  517      * We don't need to verify that there are frame pointers on the stack,
  518      * since we already did that when we called _libsafe_save_ra_fp().
  519      */
  520 
  521     fp = nextfp;
  522     }
  523 
  524     /*
  525      * We weren't able to say for sure that the stack contains valid frame
  526      * pointers, so we will return -1.
  527      */
  528     return 1;
  529 }
  530 
  531 
  532 /*
  533  * Given an address 'addr' returns 1 iff the address points to a return address
  534  * or a frame pointer on the stack.  Otherwise, it returns 0.  Note: stack
  535  * grows down, and arrays/structures grow up.
  536  */
  537 uint _libsafe_raVariableP(void *addr) {
  538     /*
  539      * Does addr point to a return address or a frame pointer on the stack?
  540      */
  541     int is_ra = 0;
  542 
  543     /*
  544      * (Vandoorselaere Yoann)
  545      * We have now just one cast.
  546      */
  547     void *fp, *sp;
  548     
  549     /*
  550      * nextfp is used in the check for -fomit-frame-pointer code.
  551      */
  552     void *nextfp;
  553 
  554     /*
  555      * stack_start is the highest address in the memory space mapped for this
  556      * stack.
  557      */
  558     void *stack_start;
  559 
  560     /*
  561      * If _libsafe_die() has been called, then we don't need to do anymore
  562      * libsafe checking.
  563      */
  564     if (dying)
  565     return 0;
  566 
  567     /*
  568      * (Arash Baratloo / Yoann Vandoorselaere)
  569      * use the stack address of the first declared variable to get the 'sp'
  570      * address in a portable way.
  571      */
  572     sp = &fp;
  573 
  574     /*
  575      * Stack grows downwards (toward 0x00).  Thus, if the stack pointer is
  576      * above (>) 'addr', 'addr' can't be on the stack.
  577      */
  578     if (sp > addr)
  579     return 0;
  580 
  581     /*
  582      * Note: the program name is always stored at 0xbffffffb (documented in the
  583      * book Linux Kernel).  Search back through the frames to find the frame
  584      * containing 'addr'.
  585      */
  586     fp = __builtin_frame_address(0);
  587 
  588     /*
  589      * Note that find_stack_start(fp) should never return NULL, since fp is
  590      * always guaranteed to be on the stack.
  591      */
  592     stack_start = find_stack_start((void*)&fp);
  593 
  594     while ((sp < fp) && (fp <= stack_start)) {
  595     if (fp == addr ||       /* addr points to a frame pointer */
  596         fp + 4 == addr)     /* addr points to a return address */
  597     {
  598         is_ra = 1;
  599         break;
  600     }
  601 
  602     nextfp = *(void **) fp;
  603 
  604     /*
  605      * The following checks are meant to detect code that doesn't insert
  606      * frame pointers onto the stack.  (i.e., code that is compiled with
  607      * -fomit-frame-pointer).
  608      */
  609 
  610     /*
  611      * Make sure frame pointers are word aligned.
  612      */
  613     if ((uint)nextfp & 0x03) {
  614         LOG(2, "fp not word aligned; bypass enabled\n");
  615         return 0;
  616     }
  617 
  618     /*
  619      * Make sure frame pointers are monotonically increasing.
  620      */
  621     if (nextfp <= fp) {
  622         LOG(2, "fp not monotonically increasing; bypass enabled\n");
  623         return 0;
  624     }
  625 
  626     fp = nextfp;
  627     }
  628 
  629     /*
  630      * If we haven't found the correct frame by now, it either means that addr
  631      * isn't on the stack or that the stack doesn't contain frame pointers.
  632      * Either way, we will return 0 to bypass checks for addr.
  633      */
  634     if (is_ra == 0) {
  635     return 0;
  636     }
  637 
  638     /*
  639      * Now check to make sure that the rest of the stack looks reasonable.
  640      */
  641     while ((sp < fp) && (fp <= stack_start)) {
  642     nextfp = *(void **) fp;
  643 
  644     if (nextfp == NULL) {
  645         /*
  646          * This is the only correct way to end the stack.
  647          */
  648         return is_ra;
  649     }
  650 
  651     /*
  652      * Make sure frame pointers are word aligned.
  653      */
  654     if ((uint)nextfp & 0x03) {
  655         LOG(2, "fp not word aligned; bypass enabled\n");
  656         return 0;
  657     }
  658 
  659     /*
  660      * Make sure frame pointers are monotonically * increasing.
  661      */
  662     if (nextfp <= fp) {
  663         LOG(2, "fp not monotonically increasing; bypass enabled\n");
  664         return 0;
  665     }
  666 
  667     fp = nextfp;
  668     }
  669 
  670     /*
  671      * We weren't able to say for sure that the stack contains valid frame
  672      * pointers, so we will return 0.
  673      */
  674     return 0;
  675 }
  676 
  677 
  678 #ifdef DUMP_STACK
  679 /* Create a new filename consisting for LIBSAFE_DUMP_STACK_FILE followed by the
  680  * PID.
  681  */
  682 void create_dump_stack_filename(char *filename, int size) {
  683     char    *p, *p2;
  684     char    buf[10];    // To hold the PID, but with digits reversed.  We
  685             //  assume that the PID is at most 10 digits.
  686     int     pid;
  687     int     count=0;    // How many chars we already put into filename
  688 
  689     // strcpy(filename, LIBSAFE_DUMP_STACK_FILE);
  690     // NOTE:  We can't use strcpy or sprintf, since they will be intercepted by
  691     // libsafe and thus cause infinite recursion.
  692     for (p=LIBSAFE_DUMP_STACK_FILE,p2=filename; *p && count<size-1; p++) {
  693     *p2++ = *p;
  694     count++;
  695     }
  696 
  697     // strcat(filename, <getpid()>)
  698     // NOTE:  We can't use strcpy or sprintf, since they will be intercepted by
  699     // libsafe and thus cause infinite recursion.
  700     pid = getpid();
  701     for (p=buf; pid>0; p++) {
  702     *p = '0' + (pid % 10);
  703     pid /= 10;
  704     }
  705     for (p--; p>=buf && count<size-1; p--) {
  706     *p2++ = *p;
  707     count++;
  708     }
  709 
  710     *p2 = (char) NULL;
  711 }
  712 
  713 /* Print the stack contents to stderr.  Use the same approximations for sp (the
  714  * top of the stack) that _libsafe_stackVariableP() uses.
  715  */
  716 void _libsafe_dump_stack(char *file, int linenum) {
  717     char    *sp;
  718     FILE    *fp=NULL;
  719     void    *current_stack_start;
  720     char    exename[MAXPATHLEN];
  721 
  722     /*
  723      * We will dump the stack contents into a file named
  724      * LIBSAFE_DUMP_STACK_FILE plus the PID of this process.  By tacking the
  725      * PID onto the filename, we allow a multi-threaded process to create stack
  726      * dump files that don't overwrite each other.
  727      */
  728     int     filename_size = strlen(LIBSAFE_DUMP_STACK_FILE) + 6;
  729     char    *filename = alloca(filename_size);
  730     create_dump_stack_filename(filename, filename_size);
  731     
  732     /*
  733      * Note that find_stack_start(fp) should never return NULL, since fp is
  734      * always guaranteed to be on the stack.
  735      */
  736     current_stack_start = find_stack_start((void*)&fp);
  737 
  738     /*
  739      * (Arash Baratloo / Yoann Vandoorselaere)
  740      * use the stack address of the first declared variable to get the 'sp'
  741      * address in a portable way.
  742      */
  743     sp = (char*)&sp;
  744 
  745     if ((fp=fopen(filename, "w")) == NULL) {
  746     /* If we can't open the dump file, then just dump to stderr. */
  747     fp = stderr;
  748     LOG(1, "Dumping stack to stderr.\n");
  749     }
  750     else {
  751     LOG(1, "Dumping stack to %s.\n", filename);
  752     }
  753 
  754 
  755 
  756 
  757 /* For debugging only!!! */
  758 {
  759     char cmd[1000];
  760     sprintf(cmd, "cat /proc/%d/maps >/tmp/maps.%d", getpid(), getpid());
  761     system(cmd);
  762     printf("Copied maps to /tmp/maps.%d\n", getpid());
  763 }
  764 
  765 
  766 
  767 
  768 
  769 
  770     fprintf(fp, "Stack dump:  sp=%p  fp=%p  stack_start=%p\n",
  771     sp, __builtin_frame_address(0), current_stack_start);
  772     fprintf(fp, "Initiating dump from file=%s linenum=%d\n", file, linenum);
  773 
  774     /*
  775      * get the name of the current executable
  776      */
  777     get_exename(exename, MAXPATHLEN);
  778     fprintf(fp, "Libsafe monitoring %s\n", exename);
  779 
  780     /*
  781      * This makes the fprintf below line up better.
  782      */
  783     sp = (char*)((uint)sp & (~0x7));
  784 
  785     /*
  786      * Print out the contents of the stack in hex, until 0x40 bytes past the
  787      * start of the stack.  Make sure we don't go past 0xbffffffb in any case
  788      * to avoid segfaults.
  789      */
  790     for (; sp<=(char*)current_stack_start+0x40 && sp<(char*)0xbffffffb; sp+=8) {
  791     fprintf(fp, "%p:  %02x %02x %02x %02x %02x %02x %02x %02x\n",
  792         sp,
  793         *sp & 0xff,
  794         *(sp+1) & 0xff,
  795         *(sp+2) & 0xff,
  796         *(sp+3) & 0xff,
  797         *(sp+4) & 0xff,
  798         *(sp+5) & 0xff,
  799         *(sp+6) & 0xff,
  800         *(sp+7) & 0xff);
  801     }
  802 
  803     if (fp != stderr)
  804     fclose(fp);
  805 }
  806 #endif /* DUMP_STACK */
  807 
  808 #ifdef NOTIFY_WITH_EMAIL
  809 
  810 #include <netinet/in.h>
  811 #include <arpa/inet.h>
  812 #ifndef __USE_GNU
  813 #define __USE_GNU 1     /* defines strnlen() */
  814 #endif
  815 #include <ctype.h>
  816 #include <string.h>
  817 #include <netdb.h>
  818 #include <time.h>
  819 
  820 /*
  821 * Read a single line of data (until the first newline) from the socket, and
  822 * throw away the data.  The loglevel specifies what to do with the data read.
  823 * <=0 means to throw the data away. >1 means to pass the data to LOG(loglevel,
  824 * ...).
  825  */
  826 static void clear_one_line(int s, int loglevel) {
  827     int     res;
  828     char    throw_away_buf[500];
  829 
  830     while ((res=recv(s, throw_away_buf, sizeof(throw_away_buf)-1, 0)) > 0) {
  831     throw_away_buf[res] = (char)NULL;
  832     if (loglevel > 0)
  833         LOG(loglevel, "%s\n", throw_away_buf);
  834     if (throw_away_buf[res-1] == '\n')
  835         break;
  836     }
  837 }
  838 
  839 /*
  840  * Send the command to the mail server.  If the expected response is received,
  841  * return 0;  else return -1.  expected should be the first digit of the
  842  * 3-digit response code.  If expected==-1, then don't check the response.
  843  */
  844 static int send_command(int s, int expected, char *format, ...) {
  845     char    response;
  846     char    command[2048];
  847     int len, res;
  848 
  849     va_list args;
  850 
  851     /*
  852      * Form the command to send
  853      */
  854     va_start(args, format);
  855     len = vsnprintf(command, sizeof(command), format, args);
  856     va_end(args);
  857 
  858     /*
  859      * Send the command
  860      */
  861     res = send(s, command, len, 0);
  862     if (res == -1) {
  863     perror("libsafe:send_command:send()");
  864     return -1;
  865     }
  866 
  867     /*
  868      * Read the response from the mail server.  Make sure that the expected
  869      * response is received.  We only check the first digit from the 3-digit
  870      * response code.
  871      */
  872     if (expected >= 0) {
  873     if ((res=recv(s, &response, 1, 0)) > 0) {
  874         if ((response - '0') != expected) {
  875         /*
  876          * If we didn't get the expected response code, then read the
  877          * full response code so we can print it out.
  878          */
  879         char    full_response[4];
  880 
  881         full_response[0] = response;
  882         recv(s, &full_response[1], 2, 0);
  883         full_response[3] = (char)NULL;
  884         LOG(1, "Sendmail error: received %s, expected %dxx: ",
  885             full_response, expected);
  886         syslog(LOG_CRIT, "Sendmail error: received %s, expected %dxx: ",
  887             full_response, expected);
  888         clear_one_line(s, 1);
  889         return -1;
  890         }
  891     }
  892 
  893     /*
  894      * We don't care about the rest of the response, so just read it and
  895      * ignore it.
  896      */
  897     clear_one_line(s, 0);
  898     }
  899 
  900     return 0;
  901 }
  902 
  903 /*
  904  * Same thing as ctime(), except that the trailing newline is truncated.
  905  */
  906 char *ctime_nonewline(const time_t *timep) {
  907     char    *p;
  908 
  909     p = ctime(timep);
  910 
  911     /*
  912      * The last non-null char in the string p should be '\n'.  We will chop
  913      * that off the string.
  914      */
  915     p[strlen(p)-1] = (char)NULL;
  916 
  917     return p;
  918 }
  919 
  920 /*
  921  * Send email to the recipient, with the message as part of the subject.
  922  */
  923 #define MAIL_PORT 25
  924 static void sendmail(char *recipient, char *message) {
  925     struct sockaddr_in  addr;
  926     struct hostent  *hostinfo;
  927     int         s;
  928     char        hostname[100];
  929     time_t      t;
  930 
  931     /*
  932      * Get the name of the local machine.
  933      */
  934     if (gethostname(hostname, sizeof(hostname))) {
  935     strncpy(hostname, "localhost", sizeof(hostname));
  936     }
  937 
  938     /*
  939      * Find the current time.  This will be used as the send time for the
  940      * email.
  941      */
  942     time(&t);
  943 
  944     if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
  945     perror("libsafe:sendmail:socket()");
  946     return;
  947     }
  948 
  949     if ((hostinfo = gethostbyname("localhost")) == NULL) {
  950     syslog(LOG_CRIT, "%s,%d: gethostbyname: %s\n", __FILE__, __LINE__,
  951         hstrerror(h_errno));
  952     return;
  953     }
  954 
  955     memset(&addr, 0, sizeof(addr));
  956     addr.sin_addr.s_addr = ((struct in_addr *)(hostinfo->h_addr))->s_addr;
  957     addr.sin_port        = htons(MAIL_PORT);
  958     addr.sin_family      = AF_INET;
  959     if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
  960     perror("libsafe:sendmail:connect()");
  961     return;
  962     }
  963 
  964     /*
  965      * Read the response (response code 220) that is sent from simply opening
  966      * the connection.
  967      */
  968     clear_one_line(s, 0);
  969     
  970     /*
  971      * Send the commands to the sendmail port.  Note that ctime_nonewline() is
  972      * used instead of ctime() because some mail transport agents choke on the
  973      * '\n' returned by ctime().
  974      */
  975     if (send_command(s, 2, "HELO %s\r\n", hostname)) return;
  976     if (send_command(s, 2, "MAIL FROM:<libsafe@%s>\r\n", hostname)) return;
  977     if (send_command(s, 2, "RCPT TO:<%s>\r\n", recipient)) return;
  978     if (send_command(s, 3, "DATA\r\n")) return;
  979     if (send_command(s, -1,
  980     "Subject: ***** libsafe violation detected *****\r\n"
  981     "To: %s\r\n"
  982     "Date: %s\r\n"
  983     "\r\n"
  984     "Libsafe violation detected on %s at %s\r\n"
  985     "%s\r\n",
  986     recipient, ctime_nonewline(&t), hostname, ctime(&t), message))
  987         return;
  988     if (send_command(s, 2, "\r\n.\r\n")) return;
  989     if (send_command(s, -1, "QUIT\r\n")) return;
  990 
  991     LOG(1, "Sent email to %s\n", recipient);
  992     syslog(LOG_CRIT, "Sent email to %s\n", recipient);
  993 }
  994 #endif  /* NOTIFY_WITH_EMAIL */
  995 
  996 
  997 
  998 #ifdef HAVE_LIBPRELUDE
  999 
 1000 #include <grp.h>
 1001 #include <pwd.h>
 1002 #include <sys/types.h>
 1003 #include <string.h>
 1004 #include <inttypes.h>
 1005 #include <netinet/in.h>
 1006 #include <libprelude/list.h>
 1007 #include <libprelude/idmef-tree.h>
 1008 #include <libprelude/idmef-tree-func.h>
 1009 #include <libprelude/prelude-io.h>
 1010 #include <libprelude/prelude-message.h>
 1011 #include <libprelude/prelude-message-buffered.h>
 1012 #include <libprelude/idmef-msg-send.h>
 1013 #include <libprelude/idmef-message-id.h>
 1014 #include <libprelude/sensor.h>
 1015 #include <sys/utsname.h>
 1016 
 1017 
 1018 
 1019 static void get_stack_trace(const char *filename, char *buf, size_t size) 
 1020 {
 1021         int ret;
 1022         uint32_t pid;
 1023         caddr_t fp, ra;
 1024         
 1025         pid = getpid();
 1026         
 1027         ret = snprintf(buf, size,
 1028         "Detected an attempt to write across stack boundary.\n"
 1029         "Terminating %s.\n"
 1030         "    uid=%d  euid=%d  pid=%d\n",
 1031         filename, getuid(), geteuid(), pid);
 1032 
 1033         /*
 1034          * Print out the call stack.  We can assume that the stack is a normal
 1035          * stack, since _libsafe_stackVariableP(), _libsafe_raVariableP(), or
 1036          * _libsafe_span_stack_frames() had to be called first.
 1037          */
 1038         ret += snprintf(buf + ret, size - ret, "Call stack:\n");
 1039         for ( fp = __builtin_frame_address(0); *fp; fp = *(void **) fp ) {
 1040                 ra = *((caddr_t*)(fp+4));
 1041                 ret += snprintf(buf + ret, size - ret, "    %p\n",
 1042             (caddr_t)((uint)ra-5));
 1043         }
 1044 }
 1045 
 1046 
 1047 
 1048 static int set_user_infos(idmef_user_t *user)
 1049 {
 1050         struct passwd *uent;
 1051         struct group *gent;
 1052         idmef_userid_t *userid;
 1053         uid_t uid, euid;
 1054         gid_t gid, egid;
 1055 
 1056         uid = getuid();
 1057         euid = geteuid();
 1058         gid = getgid();
 1059         egid = getegid();
 1060         
 1061         /*
 1062          * real user id.
 1063          */
 1064         userid = idmef_user_userid_new(user);
 1065         if (! userid )
 1066                 return -1;
 1067         
 1068         userid->type = original_user;
 1069         userid->number = uid;
 1070         
 1071         uent = getpwuid(uid);
 1072         if ( uent )
 1073                 idmef_string_set(&userid->name, uent->pw_name);
 1074                 
 1075         /*
 1076          * effective user id
 1077          */
 1078         userid = idmef_user_userid_new(user);
 1079         if (! userid )
 1080                 return -1;
 1081         
 1082         userid->type = user_privs;
 1083         userid->number = euid;
 1084         uent = getpwuid(euid);
 1085         if ( uent )
 1086                 idmef_string_set(&userid->name, uent->pw_name);
 1087 
 1088         /*
 1089          * real group id
 1090          */
 1091         userid = idmef_user_userid_new(user);
 1092         if (! userid )
 1093                 return -1;
 1094         
 1095         userid->type = current_group;
 1096         userid->number = gid;
 1097         gent = getgrgid(gid);
 1098         if ( gent )
 1099                 idmef_string_set(&userid->name, gent->gr_name);
 1100         
 1101         /*
 1102          * Effective group id
 1103          */
 1104         userid = idmef_user_userid_new(user);
 1105         if (! userid )
 1106                 return -1;
 1107         
 1108         userid->type = group_privs;
 1109         userid->number = egid;
 1110         gent = getgrgid(egid);
 1111         if ( gent )
 1112                 idmef_string_set(&userid->name, gent->gr_name);
 1113 
 1114         return 0;
 1115 }
 1116 
 1117 
 1118 
 1119 
 1120 static void fill_assessment(idmef_assessment_t *assessment) 
 1121 {
 1122         idmef_action_t *action;
 1123         
 1124         idmef_assessment_impact_new(assessment);
 1125         
 1126         assessment->impact->severity = impact_high;
 1127         assessment->impact->completion = failed;
 1128         assessment->impact->type = admin;
 1129 
 1130         if ( getuid() == 0 || geteuid() == 0 )
 1131                 assessment->impact->type = admin;
 1132         else
 1133                 assessment->impact->type = user;
 1134         
 1135         idmef_string_set_constant(&assessment->impact->description,
 1136         "Stack overflow attempt detected and avoided by libsafe");
 1137         idmef_assessment_confidence_new(assessment);
 1138         assessment->confidence->rating = high;
 1139 
 1140         action = idmef_assessment_action_new(assessment);
 1141         if ( ! action )
 1142                 return;
 1143 
 1144         action->category = taken_offline;
 1145         idmef_string_set_constant(&action->description,
 1146         "Libsafe killed the target process in order to prevent the "
 1147         "overflow attack from succeeding");
 1148 }
 1149 
 1150 
 1151 
 1152 
 1153 
 1154 static void prelude_alert(char *filename) 
 1155 {
 1156         int ret;
 1157         char *program;
 1158         idmef_user_t *user;
 1159         idmef_alert_t *alert;
 1160         struct utsname utsbuf;
 1161         idmef_message_t *idmef;
 1162         idmef_target_t *target;
 1163         idmef_process_t *process;
 1164         prelude_msgbuf_t *msgbuf;
 1165         char buf[8192], hostname[255];
 1166         idmef_additional_data_t *data;
 1167         idmef_classification_t *classification;        
 1168         
 1169         
 1170         ret = prelude_sensor_init("libsafe", NULL, 0, NULL);
 1171         if ( ret < 0 ) {
 1172                 fprintf(stderr, "couldn't initialize the Prelude library\n");
 1173                 return;
 1174         }
 1175 
 1176         /*
 1177          * separate program name from pathname.
 1178          */
 1179         program = strrchr(filename, '/');
 1180         if ( program ) {
 1181                 *program = '\0';
 1182                 program++;
 1183         }
 1184         
 1185         get_stack_trace(filename, buf, sizeof(buf));
 1186         
 1187         idmef = idmef_message_new();
 1188         if ( ! idmef )
 1189                 return;
 1190 
 1191         /*
 1192          * fill alert / analyzer informations
 1193          */
 1194         idmef_alert_new(idmef);
 1195         alert = idmef->message.alert;
 1196         idmef_alert_assessment_new(alert);
 1197 
 1198         fill_assessment(alert->assessment);
 1199         
 1200         idmef_string_set_constant(&alert->analyzer.model, "Libsafe");
 1201         idmef_string_set_constant(&alert->analyzer.class,
 1202         "Stack Overflow Detection Library");
 1203         idmef_string_set_constant(&alert->analyzer.version, VERSION);
 1204 
 1205         /*
 1206          * Fill analyzer process informations.
 1207          */
 1208         idmef_analyzer_process_new(&alert->analyzer);
 1209         alert->analyzer.process->pid = getpid();
 1210         idmef_string_set(&alert->analyzer.process->name, program);
 1211         idmef_string_set(&alert->analyzer.process->path, filename);
 1212 
 1213         ret = uname(&utsbuf);
 1214         if ( ret < 0 )
 1215                 goto err;
 1216 
 1217         idmef_string_set(&alert->analyzer.ostype, utsbuf.sysname);
 1218         idmef_string_set(&alert->analyzer.osversion, utsbuf.release);
 1219 
 1220         /*
 1221          * Fill analyzer node infomations.
 1222          */
 1223         idmef_analyzer_node_new(&alert->analyzer);
 1224         gethostname(hostname, sizeof(hostname));
 1225         idmef_string_set(&alert->analyzer.node->name, hostname);
 1226 
 1227         /*
 1228          * target informations
 1229          */
 1230         target = idmef_alert_target_new(alert);
 1231         if ( ! target )
 1232                 goto err;
 1233 
 1234         user = idmef_target_user_new(target);
 1235         if ( ! user )
 1236                 goto err;
 1237         
 1238         user->category = application;
 1239         
 1240         ret = set_user_infos(user);
 1241         if ( ret < 0 )
 1242                 goto err;
 1243         
 1244         process = idmef_target_process_new(target);
 1245         idmef_string_set(&process->name, program);
 1246         process->pid  = getpid();
 1247         idmef_string_set(&process->path, filename);
 1248 
 1249         /*
 1250          * Attack classification
 1251          */
 1252         classification = idmef_alert_classification_new(alert);
 1253         if ( ! classification )
 1254                 goto err;
 1255 
 1256         idmef_string_set_constant(&classification->name,
 1257         "Stack Overflow Attempt");
 1258 
 1259         /*
 1260          * Include the call trace.
 1261          */
 1262         data = idmef_alert_additional_data_new(alert);
 1263         if ( ! data )
 1264                 goto err;
 1265         
 1266         data->type = string;
 1267         idmef_string_set_constant(&data->meaning, "Stack overflow data");
 1268         idmef_additional_data_set_data(data, string, buf, strlen(buf) + 1);
 1269 
 1270         /*
 1271          * send the message synchronously (use 1 for asynchronous send).
 1272          */
 1273         msgbuf = prelude_msgbuf_new(0);
 1274         if ( ! msgbuf )
 1275                 goto err;
 1276         
 1277         idmef_msg_send(msgbuf, idmef, PRELUDE_MSG_PRIORITY_HIGH);
 1278         idmef_message_free(idmef);
 1279         prelude_msgbuf_close(msgbuf);
 1280         
 1281         return;
 1282         
 1283   err:
 1284         idmef_message_free(idmef);
 1285         LOG(1, "error writing an IDMEF message.\n");
 1286 }
 1287 
 1288 #endif /* NOTIFY_WITH_PRELUDE */
 1289 
 1290 
 1291 /*
 1292  * Sanity check for stack frame pointers.  Return 0 if the check passes.  Else
 1293  * return 1.
 1294  */
 1295 static int check_nextfp(caddr_t fp, caddr_t nextfp) {
 1296     caddr_t stack_start = find_stack_start((void*)&fp);
 1297 
 1298     /*
 1299      * The following checks are meant to detect code that doesn't insert
 1300      * frame pointers onto the stack.  (i.e., code that is compiled with
 1301      * -fomit-frame-pointer).
 1302      */
 1303 
 1304     if (nextfp > stack_start) {
 1305     LOG(2, "fp > stack_start; bypass enabled\n");
 1306     _libsafe_exclude = 1;
 1307     return 1;
 1308     }
 1309 
 1310     /*
 1311      * Make sure frame pointers are word aligned.
 1312      */
 1313     if ((uint)nextfp & 0x03) {
 1314     LOG(2, "fp not word aligned; bypass enabled\n");
 1315     _libsafe_exclude = 1;
 1316     return 1;
 1317     }
 1318 
 1319     /*
 1320      * Make sure frame pointers are monotonically increasing.
 1321      */
 1322     if (nextfp <= fp) {
 1323     LOG(2, "fp not monotonically increasing; bypass enabled\n");
 1324     _libsafe_exclude = 1;
 1325     return 1;
 1326     }
 1327 
 1328     return 0;
 1329 }
 1330 
 1331 
 1332 struct maps_st {
 1333     caddr_t start, end;
 1334     char    *path;
 1335 };
 1336 
 1337 
 1338 /*
 1339  * Read /proc/<pid>/maps to find the memory-mapped regions for this process.
 1340  */
 1341 static int get_memory_maps(struct maps_st **mapsptr) {
 1342     struct maps_st  *maps = NULL;
 1343     char    filename[200], buf[500];
 1344     FILE    *fp;
 1345     int     count, i;
 1346     char    *p;
 1347 
 1348     snprintf(filename, sizeof(filename), "/proc/%d/maps", getpid());
 1349 
 1350     /*
 1351      * First pass:  Find out how many memory regions there are.
 1352      */
 1353     if ((fp=fopen(filename, "r")) == NULL) {
 1354     return 0;
 1355     }
 1356 
 1357     count = 0;
 1358     while (fgets(buf, sizeof(buf), fp)) {
 1359     count++;
 1360     }
 1361 
 1362     fclose(fp);
 1363 
 1364     maps = (struct maps_st *) malloc(count * sizeof(struct maps_st));
 1365     *mapsptr = maps;
 1366 
 1367     /*
 1368      * Second pass:  Fill in the table with the region info.
 1369      */
 1370     if ((fp=fopen(filename, "r")) == NULL) {
 1371     if (maps) free(maps);
 1372     return 0;
 1373     }
 1374 
 1375     i = 0;
 1376     while (fgets(buf, sizeof(buf), fp) && i < count) {
 1377     sscanf(buf, "%p-%p", &maps[i].start, &maps[i].end);
 1378     p = strchr(buf, '/');
 1379     if (p) {
 1380         maps[i].path = strdup(p);
 1381         
 1382         /*
 1383          * Strip off the trailing newline.
 1384          */
 1385         p = strchr(maps[i].path, '\n');
 1386         if (p) *p = (char)NULL;
 1387     }
 1388     else
 1389     {
 1390         maps[i].path = NULL;
 1391     }
 1392     i++;
 1393     }
 1394 
 1395     fclose(fp);
 1396 
 1397     return count;
 1398 }
 1399 
 1400 
 1401 /*
 1402  * Return the index into the maps array that corresponds to the caller_addr.
 1403  * If caller_addr is not in any of the regions in maps, then return -1.
 1404  */
 1405 static int find_caller_addr(struct maps_st *maps, int count, caddr_t
 1406     caller_addr)
 1407 {
 1408     int i;
 1409 
 1410     for (i=0; i<count; i++) {
 1411     if (caller_addr >= maps[i].start && caller_addr <= maps[i].end)
 1412         return i;
 1413     }
 1414 
 1415     return -1;
 1416 }
 1417 
 1418 
 1419 /*
 1420  * This is what is called when a violation is detected.  If you want to add
 1421  * customized actions triggered by detection put them here.  (format,...) is
 1422  * similar to printf() and passed to syslog().
 1423  */
 1424 void _libsafe_warn(char *format, ...)
 1425 {
 1426     char    exename[MAXPATHLEN];
 1427     va_list args;
 1428     struct maps_st  *maps;
 1429     int     count, index;
 1430 
 1431     dying = 1;
 1432 
 1433     /*
 1434      * get the name of the current executable
 1435      */
 1436     get_exename(exename, MAXPATHLEN);
 1437     
 1438     va_start(args, format);
 1439 
 1440     count = get_memory_maps(&maps);
 1441 
 1442     /*
 1443      * add an entry to syslog()
 1444      */
 1445 #ifdef DEBUG_TURN_OFF_SYSLOG
 1446     LOG(1, "Turned off syslog entries for debugging.\n");
 1447 #else
 1448     openlog(LIBNAME, LOG_CONS | LOG_PID, LOG_AUTHPRIV);
 1449     syslog(LOG_CRIT, "Libsafe version %s", VERSION);
 1450     syslog(LOG_CRIT, "Detected an attempt to write across stack boundary.");
 1451     syslog(LOG_CRIT, "Terminating %s.", exename);
 1452     syslog(LOG_CRIT, "    uid=%d  euid=%d  pid=%d", getuid(), geteuid(),
 1453         getpid());
 1454 #endif
 1455     LOG(1, "Libsafe version %s\n", VERSION);
 1456     LOG(1, "Detected an attempt to write across stack boundary.\n");
 1457     LOG(1, "Terminating %s.\n", exename);
 1458     LOG(1, "    uid=%d  euid=%d  pid=%d\n", getuid(), geteuid(), getpid());
 1459 
 1460     {
 1461     /*
 1462      * Print out the call stack.  We can assume that the stack is a normal
 1463      * stack, since _libsafe_stackVariableP(), _libsafe_raVariableP(), or
 1464      * _libsafe_span_stack_frames() had to be called first.
 1465      */
 1466     caddr_t fp, ra, nextfp, caller_addr;
 1467 #ifndef DEBUG_TURN_OFF_SYSLOG
 1468     syslog(LOG_CRIT, "Call stack:\n");
 1469 #endif
 1470     LOG(1, "Call stack:\n");
 1471 
 1472     for (fp=__builtin_frame_address(0); *fp; fp=nextfp) {
 1473         ra = *((caddr_t*)(fp+4));
 1474 
 1475         /*
 1476          * Find the memory region and corresponding mapped file associated
 1477          * with this address.
 1478          */
 1479         caller_addr = (caddr_t)((uint)ra-5);
 1480         index = find_caller_addr(maps, count, caller_addr);
 1481 
 1482 #ifndef DEBUG_TURN_OFF_SYSLOG
 1483         syslog(LOG_CRIT, "    %p  %s\n", caller_addr, maps[index].path);
 1484 #endif
 1485         LOG(1, "    %p\t%s\n", caller_addr, maps[index].path);
 1486 
 1487         nextfp = *(void **)fp;
 1488         if (check_nextfp(fp, nextfp))
 1489         break;
 1490     }
 1491     }
 1492 #ifndef DEBUG_TURN_OFF_SYSLOG
 1493     syslog(LOG_CRIT, format, args);
 1494 #endif
 1495     if (1 <= LOG_LEVEL) {
 1496     vfprintf(stderr, format, args);
 1497     fprintf(stderr, "\n");
 1498     }
 1499 
 1500     va_end(args);
 1501 
 1502     /*
 1503      * PUT ANY CUSTOMIZED ACTIONS HERE...
 1504      */
 1505 
 1506 #ifdef HAVE_LIBPRELUDE
 1507     prelude_alert(exename);
 1508 #endif
 1509     
 1510 #ifdef DUMP_STACK
 1511     /* Print the contents of the stack */
 1512     _libsafe_dump_stack(__FILE__, __LINE__);
 1513 #endif
 1514 
 1515 #ifdef NOTIFY_WITH_EMAIL
 1516     {
 1517     char errmsg[1000];
 1518     char buf[1000];
 1519     char recipient[500];
 1520     FILE *fp;
 1521 
 1522     /*
 1523      * Form the descriptive message.
 1524      */
 1525     snprintf(errmsg, sizeof(errmsg),
 1526         "Libsafe version %s\r\n"
 1527         "Detected an attempt to write across stack boundary.\r\n"
 1528         "Terminating %s.\r\n"
 1529         "    uid=%d  euid=%d  pid=%d\r\n",
 1530         VERSION,
 1531         exename,
 1532         getuid(), geteuid(), getpid());
 1533     {
 1534         /*
 1535          * Print out the call stack.  We can assume that the stack is a
 1536          * normal stack, since _libsafe_stackVariableP(),
 1537          * _libsafe_raVariableP(), or _libsafe_span_stack_frames() had to
 1538          * be called first.
 1539          */
 1540         caddr_t fp, ra, nextfp, caller_addr;
 1541         struct maps_st  *maps;
 1542         int     count, index;
 1543 
 1544         count = get_memory_maps(&maps);
 1545 
 1546         snprintf(buf, sizeof(buf), "Call stack:\r\n");
 1547         strncat(errmsg, buf,
 1548         sizeof(errmsg) - strnlen(errmsg,sizeof(errmsg)) - 1);
 1549         for (fp=__builtin_frame_address(0); *fp; fp=nextfp) {
 1550         ra = *((caddr_t*)(fp+4));
 1551 
 1552         /*
 1553          * Find the memory region and corresponding mapped file
 1554          * associated with this address.
 1555          */
 1556         caller_addr = (caddr_t)((uint)ra-5);
 1557         index = find_caller_addr(maps, count, caller_addr);
 1558 
 1559         snprintf(buf, sizeof(buf), "    %p\t%s\r\n", caller_addr,
 1560             maps[index].path);
 1561         strncat(errmsg, buf,
 1562             sizeof(errmsg) - strnlen(errmsg,sizeof(errmsg)) - 1);
 1563 
 1564         nextfp = *(void **)fp;
 1565         if (check_nextfp(fp, nextfp))
 1566             break;
 1567         }
 1568     }
 1569 #ifdef DUMP_STACK
 1570     {
 1571         /*
 1572          * We will dump the stack contents into a file named
 1573          * LIBSAFE_DUMP_STACK_FILE plus the PID of this process.  By
 1574          * tacking the PID onto the filename, we allow a multi-threaded
 1575          * process to create stack dump files that don't overwrite each
 1576          * other.
 1577          */
 1578         int     filename_size = strlen(LIBSAFE_DUMP_STACK_FILE) + 6;
 1579         char    *filename = alloca(filename_size);
 1580         create_dump_stack_filename(filename, filename_size);
 1581         snprintf(buf, sizeof(buf), "Dumped stack to %s.\r\n", filename);
 1582         strncat(errmsg, buf,
 1583         sizeof(errmsg) - strnlen(errmsg,sizeof(errmsg)) - 1);
 1584     }
 1585 #endif
 1586     
 1587     va_start(args, format);
 1588     vsnprintf(buf, sizeof(buf), format, args);
 1589     va_end(args);
 1590     strncat(errmsg, buf,
 1591         sizeof(errmsg) - strnlen(errmsg,sizeof(errmsg)) - 1);
 1592 
 1593     /*
 1594      * If the mail_list file exists, then send email to all the recipients
 1595      * listed in that file.  Otherwise, send email to root@localhost.
 1596      */
 1597     if ((fp = fopen("/etc/libsafe.notify", "r")) == NULL) {
 1598         sendmail("root@localhost", errmsg);
 1599     } else {
 1600         while (fgets(recipient, sizeof(recipient), fp)) {
 1601         char *p;
 1602 
 1603         /*
 1604          * Chop off any trailing newlines if present
 1605          */
 1606         for (p=recipient + strnlen(recipient, sizeof(recipient)) - 1;
 1607              isspace(*p);
 1608              p--)
 1609         {
 1610             *p = (char) NULL;
 1611         }
 1612         
 1613         sendmail(recipient, errmsg);
 1614         }
 1615         fclose(fp);
 1616     }
 1617     }
 1618 #endif  /* NOTIFY_WITH_EMAIL */
 1619 
 1620     if (maps)
 1621     free(maps);
 1622 
 1623     /*
 1624      * Since we are justing doing a warning, set dying=0 to indicate that we
 1625      * should resume libsafe checking now.
 1626      */
 1627     dying = 0;
 1628 }
 1629 
 1630 /*
 1631  * This is what is called when a buffer overflow on the stack is detected.  If
 1632  * you want to add customized actions triggered by detection put them here.
 1633  * 'name' is the name of this library, and (format,...) is similar to printf()
 1634  * and passed to syslog().
 1635  */
 1636 void _libsafe_die(char *format, ...)
 1637 {
 1638     va_list args;
 1639 
 1640     dying = 1;
 1641 
 1642     va_start(args, format);
 1643     _libsafe_warn(format, args);
 1644     va_end(args);
 1645 
 1646 #ifdef DUMP_CORE
 1647     /*
 1648      * Kill this process, but generate a core dump in the /tmp directory.  If
 1649      * there is no /tmp directory, the core dump is placed in the current
 1650      * working directory, wherever that is.
 1651      *
 1652      * signal() is needed to disabled any registered handlers for SIGABRT,
 1653      * which is used by abort().  Doing a chdir("/tmp") makes it easier to find
 1654      * where the core dump file is.  However, if /tmp/core already exists and
 1655      * is owned by another user, then no core dump file will be generated.
 1656      */
 1657     signal(SIGABRT, SIG_IGN);
 1658     if (chdir("/tmp")) {
 1659     LOG(1, "Dumping core to /tmp.");
 1660     }
 1661     else {
 1662     char dirname[100];
 1663     getcwd(dirname, sizeof(dirname));
 1664     LOG(1, "Dumping core to %s.\n", dirname);
 1665     }
 1666     {
 1667     /*
 1668      * setrlimit() makes sure that we can produce a core dump file.
 1669      */
 1670     struct rlimit rlim = {0, RLIM_INFINITY};
 1671     setrlimit(RLIMIT_CORE, &rlim);
 1672     }
 1673     abort();
 1674 #else
 1675     /*
 1676      * (Vandoorselaere Yoann)
 1677      * let's do that in a cleaner way, don't use code to generate sigsegv cause
 1678      * it can be handled... use _exit().
 1679      *
 1680      * _exit() doesn't kill multi-threaded processes properly, so now we use
 1681      * SIGKILL.  There might be a concern with delayed signal delivery, but at
 1682      * least it kills all threads and can't be caught. -- tkt
 1683      */
 1684     //_exit(1);
 1685     raise(SIGKILL);
 1686 #endif
 1687 }
 1688 
 1689