Home | History | Annotate | Download | only in tests
      1 #ifdef HAVE_CONFIG_H
      2 # include "config.h"
      3 #endif
      4 #include <dlfcn.h>
      5 #include <fcntl.h>
      6 #include <unistd.h>
      7 #include <sys/mman.h>
      8 #include <sys/wait.h>
      9 #include <sys/sendfile.h>
     10 
     11 int main(void)
     12 {
     13 	const unsigned long pagesize = sysconf(_SC_PAGESIZE);
     14 
     15 #ifdef __s390__
     16 	/*
     17 	 * The si_addr field is unreliable:
     18 	 * https://marc.info/?l=linux-s390&m=142515870124248&w=2
     19 	 */
     20 	return 77;
     21 #endif
     22 
     23 	/* write instruction pointer length to the log */
     24 	if (write(-1, NULL, 2 * sizeof(void *)) >= 0)
     25 		return 77;
     26 
     27 	/* just a noticeable line in the log */
     28 	if (munmap(&main, 0) >= 0)
     29 		return 77;
     30 
     31 	int pid = fork();
     32 	if (pid < 0)
     33 		return 77;
     34 
     35 	if (!pid) {
     36 		const unsigned long mask = ~(pagesize - 1);
     37 		unsigned long addr = (unsigned long) &main & mask;
     38 		unsigned long size = pagesize << 1;
     39 
     40 #ifdef HAVE_DLADDR
     41 		Dl_info info;
     42 		if (dladdr(&main, &info)) {
     43 			const unsigned long base =
     44 				(unsigned long) info.dli_fbase & mask;
     45 			if (base < addr) {
     46 				size += addr - base;
     47 				addr = base;
     48 			}
     49 		} else
     50 #endif
     51 		{
     52 			addr -= size;
     53 			size <<= 1;
     54 		}
     55 
     56 		/* SIGSEGV is expected */
     57 		(void) munmap((void *) addr, size);
     58 		(void) munmap((void *) addr, size);
     59 		return 77;
     60 	}
     61 
     62 	int status;
     63 	if (wait(&status) != pid ||
     64 	    !WIFSIGNALED(status) ||
     65 	    WTERMSIG(status) != SIGSEGV)
     66 		return 77;
     67 
     68 	/* dump process map for debug purposes */
     69 	close(0);
     70 	if (!open("/proc/self/maps", O_RDONLY))
     71 		(void) sendfile(1, 0, NULL, pagesize);
     72 
     73 	return 0;
     74 }
     75