2015-12-17 17:56:48 +00:00
/*
2016-01-06 11:33:13 +00:00
* Copyright ( c ) 2015 - 2016 Dmitry V . Levin < ldv @ altlinux . org >
2015-12-17 17:56:48 +00:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2016-01-02 13:28:43 +00:00
# include "tests.h"
2016-01-06 11:33:13 +00:00
# include <assert.h>
2015-02-27 04:09:56 +00:00
# include <dlfcn.h>
2015-02-23 22:37:40 +00:00
# include <fcntl.h>
2015-02-15 15:52:02 +00:00
# include <unistd.h>
# include <sys/mman.h>
# include <sys/wait.h>
2015-02-23 22:37:40 +00:00
# include <sys/sendfile.h>
2015-02-15 15:52:02 +00:00
int main ( void )
{
2016-01-06 11:33:13 +00:00
const unsigned long pagesize = get_page_size ( ) ;
2015-02-15 15:52:02 +00:00
2015-03-02 20:04:34 -05:00
# ifdef __s390__
/*
* The si_addr field is unreliable :
* https : //marc.info/?l=linux-s390&m=142515870124248&w=2
*/
2016-01-06 11:33:13 +00:00
error_msg_and_skip ( " s390: si_addr is unreliable " ) ;
2015-03-02 20:04:34 -05:00
# endif
2015-02-15 15:52:02 +00:00
/* write instruction pointer length to the log */
2016-01-06 11:33:13 +00:00
assert ( write ( - 1 , NULL , 2 * sizeof ( void * ) ) < 0 ) ;
2015-02-23 22:37:40 +00:00
2015-02-15 15:52:02 +00:00
/* just a noticeable line in the log */
2016-01-06 11:33:13 +00:00
assert ( munmap ( & main , 0 ) < 0 ) ;
2015-02-15 15:52:02 +00:00
int pid = fork ( ) ;
if ( pid < 0 )
2016-01-06 11:33:13 +00:00
perror_msg_and_fail ( " fork " ) ;
2015-02-15 15:52:02 +00:00
if ( ! pid ) {
2015-02-27 04:09:56 +00:00
const unsigned long mask = ~ ( pagesize - 1 ) ;
unsigned long addr = ( unsigned long ) & main & mask ;
unsigned long size = pagesize < < 1 ;
# ifdef HAVE_DLADDR
Dl_info info ;
if ( dladdr ( & main , & info ) ) {
const unsigned long base =
( unsigned long ) info . dli_fbase & mask ;
if ( base < addr ) {
size + = addr - base ;
addr = base ;
}
} else
# endif
{
addr - = size ;
size < < = 1 ;
}
2015-02-23 22:37:40 +00:00
2015-02-15 15:52:02 +00:00
/* SIGSEGV is expected */
2015-02-27 04:09:56 +00:00
( void ) munmap ( ( void * ) addr , size ) ;
( void ) munmap ( ( void * ) addr , size ) ;
2016-01-06 11:33:13 +00:00
error_msg_and_skip ( " SIGSEGV did not happen " ) ;
2015-02-15 15:52:02 +00:00
}
int status ;
2016-01-06 11:33:13 +00:00
assert ( wait ( & status ) = = pid ) ;
assert ( WIFSIGNALED ( status ) ) ;
assert ( WTERMSIG ( status ) = = SIGSEGV ) ;
2015-02-15 15:52:02 +00:00
2015-02-23 22:37:40 +00:00
/* dump process map for debug purposes */
close ( 0 ) ;
if ( ! open ( " /proc/self/maps " , O_RDONLY ) )
2015-02-27 04:09:56 +00:00
( void ) sendfile ( 1 , 0 , NULL , pagesize ) ;
2015-02-23 22:37:40 +00:00
2015-02-15 15:52:02 +00:00
return 0 ;
}