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"; 23my $target_arch; 24 25sub execstack($) { 26 my ( $file ) = @_; 27 my @output; 28 my @stack; 29 my $tool; 30 if($target_arch eq "mic") { 31 $tool = "x86_64-k1om-linux-readelf"; 32 } else { 33 $tool = "readelf"; 34 } 35 execute( [ $tool, "-l", "-W", $file ], -stdout => \@output ); 36 @stack = grep( $_ =~ m{\A\s*(?:GNU_)?STACK\s+}, @output ); 37 if ( not @stack ) { 38 # Interpret missed "STACK" line as error. 39 runtime_error( "$file: No stack segment found; looks like stack would be executable." ); 40 }; # if 41 if ( @stack > 1 ) { 42 runtime_error( "$file: More than one stack segment found.", "readelf output:", @output, "(eof)" ); 43 }; # if 44 # Typical stack lines are: 45 # Linux* OS IA-32 architecture: 46 # GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4 47 # Linux* OS Intel(R) 64: 48 # GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RWE 0x8 49 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} ) { 50 runtime_error( "$file: Cannot parse stack segment line:", ">>> $stack[ 0 ]" ); 51 }; # if 52 my $attrs = $1; 53 if ( $attrs =~ m{E} ) { 54 runtime_error( "$file: Stack is executable" ); 55 }; # if 56}; # sub execstack 57 58get_options( 59 "arch=s" => \$target_arch, 60); 61 62foreach my $file ( @ARGV ) { 63 execstack( $file ); 64}; # foreach $file 65 66exit( 0 ); 67 68__END__ 69 70=pod 71 72=head1 NAME 73 74B<check-execstack.pl> -- Check whether stack is executable, issue an error if so. 75 76=head1 SYNOPSIS 77 78B<check-execstack.pl> I<optiion>... I<file>... 79 80=head1 DESCRIPTION 81 82The script checks whether stack of specified executable file, and issues error if stack is 83executable. If stack is not executable, the script exits silently with zero exit code. 84 85The script runs C<readelf> utility to get information about specified executable file. So, the 86script fails if C<readelf> is not available. Effectively it means the script works only on Linux* OS 87(and, probably, Intel(R) Many Integrated Core Architecture). 88 89=head1 OPTIONS 90 91=over 92 93=item Standard Options 94 95=over 96 97=item B<--doc> 98 99=item B<--manual> 100 101Print full help message and exit. 102 103=item B<--help> 104 105Print short help message and exit. 106 107=item B<--usage> 108 109Print very short usage message and exit. 110 111=item B<--verbose> 112 113Do print informational messages. 114 115=item B<--version> 116 117Print program version and exit. 118 119=item B<--quiet> 120 121Work quiet, do not print informational messages. 122 123=back 124 125=back 126 127=head1 ARGUMENTS 128 129=over 130 131=item I<file> 132 133A name of executable or shared object to check. Multiple files may be specified. 134 135=back 136 137=head1 EXAMPLES 138 139Check libomp.so library: 140 141 $ check-execstack.pl libomp.so 142 143=cut 144 145# end of file # 146 147