1#!/usr/bin/perl 2 3# 4#//===----------------------------------------------------------------------===// 5#// 6#// The LLVM Compiler Infrastructure 7#// 8#// This file is dual licensed under the MIT and the University of Illinois Open 9#// Source Licenses. See LICENSE.txt for details. 10#// 11#//===----------------------------------------------------------------------===// 12# 13 14use strict; 15use warnings; 16 17use FindBin; 18use lib "$FindBin::Bin/lib"; 19 20use tools; 21 22our $VERSION = "0.002"; 23 24sub execstack($) { 25 my ( $file ) = @_; 26 my @output; 27 my @stack; 28 execute( [ "readelf", "-l", "-W", $file ], -stdout => \@output ); 29 @stack = grep( $_ =~ m{\A\s*(?:GNU_)?STACK\s+}, @output ); 30 if ( not @stack ) { 31 # Interpret missed "STACK" line as error. 32 runtime_error( "$file: No stack segment found; looks like stack would be executable." ); 33 }; # if 34 if ( @stack > 1 ) { 35 runtime_error( "$file: More than one stack segment found.", "readelf output:", @output, "(eof)" ); 36 }; # if 37 # Typical stack lines are: 38 # Linux* OS IA-32 architecture: 39 # GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4 40 # Linux* OS Intel(R) 64: 41 # GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RWE 0x8 42 if ( $stack[ 0 ] !~ m{\A\s*(?:GNU_)?STACK(?:\s+0x[0-9a-f]+){5}\s+([R ][W ][E ])\s+0x[0-9a-f]+\s*\z} ) { 43 runtime_error( "$file: Cannot parse stack segment line:", ">>> $stack[ 0 ]" ); 44 }; # if 45 my $attrs = $1; 46 if ( $attrs =~ m{E} ) { 47 runtime_error( "$file: Stack is executable" ); 48 }; # if 49}; # sub execstack 50 51get_options( 52); 53 54foreach my $file ( @ARGV ) { 55 execstack( $file ); 56}; # foreach $file 57 58exit( 0 ); 59 60__END__ 61 62=pod 63 64=head1 NAME 65 66B<check-execstack.pl> -- Check whether stack is executable, issue an error if so. 67 68=head1 SYNOPSIS 69 70B<check-execstack.pl> I<optiion>... I<file>... 71 72=head1 DESCRIPTION 73 74The script checks whether stack of specified executable file, and issues error if stack is 75executable. If stack is not executable, the script exits silently with zero exit code. 76 77The script runs C<readelf> utility to get information about specified executable file. So, the 78script fails if C<readelf> is not available. Effectively it means the script works only on Linux* OS 79(and, probably, Intel(R) Many Integrated Core Architecture). 80 81=head1 OPTIONS 82 83=over 84 85=item Standard Options 86 87=over 88 89=item B<--doc> 90 91=item B<--manual> 92 93Print full help message and exit. 94 95=item B<--help> 96 97Print short help message and exit. 98 99=item B<--usage> 100 101Print very short usage message and exit. 102 103=item B<--verbose> 104 105Do print informational messages. 106 107=item B<--version> 108 109Print program version and exit. 110 111=item B<--quiet> 112 113Work quiet, do not print informational messages. 114 115=back 116 117=back 118 119=head1 ARGUMENTS 120 121=over 122 123=item I<file> 124 125A name of executable or shared object to check. Multiple files may be specified. 126 127=back 128 129=head1 EXAMPLES 130 131Check libiomp5.so library: 132 133 $ check-execstack.pl libiomp5.so 134 135=cut 136 137# end of file # 138 139