"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