Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 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 | |
| 14 | use strict; |
| 15 | use warnings; |
| 16 | |
| 17 | use FindBin; |
| 18 | use lib "$FindBin::Bin/lib"; |
| 19 | |
| 20 | use tools; |
| 21 | |
| 22 | our $VERSION = "0.002"; |
Jonathan Peyton | 4c91ad1 | 2016-01-26 19:44:31 +0000 | [diff] [blame] | 23 | my $target_arch; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 24 | |
| 25 | sub execstack($) { |
| 26 | my ( $file ) = @_; |
| 27 | my @output; |
| 28 | my @stack; |
Andrey Churbanov | d315cea | 2015-01-16 12:54:51 +0000 | [diff] [blame] | 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 ); |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 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 | |
| 58 | get_options( |
Jonathan Peyton | 4c91ad1 | 2016-01-26 19:44:31 +0000 | [diff] [blame] | 59 | "arch=s" => \$target_arch, |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 60 | ); |
| 61 | |
| 62 | foreach my $file ( @ARGV ) { |
| 63 | execstack( $file ); |
| 64 | }; # foreach $file |
| 65 | |
| 66 | exit( 0 ); |
| 67 | |
| 68 | __END__ |
| 69 | |
| 70 | =pod |
| 71 | |
| 72 | =head1 NAME |
| 73 | |
| 74 | B<check-execstack.pl> -- Check whether stack is executable, issue an error if so. |
| 75 | |
| 76 | =head1 SYNOPSIS |
| 77 | |
| 78 | B<check-execstack.pl> I<optiion>... I<file>... |
| 79 | |
| 80 | =head1 DESCRIPTION |
| 81 | |
| 82 | The script checks whether stack of specified executable file, and issues error if stack is |
| 83 | executable. If stack is not executable, the script exits silently with zero exit code. |
| 84 | |
| 85 | The script runs C<readelf> utility to get information about specified executable file. So, the |
| 86 | script 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 | |
| 101 | Print full help message and exit. |
| 102 | |
| 103 | =item B<--help> |
| 104 | |
| 105 | Print short help message and exit. |
| 106 | |
| 107 | =item B<--usage> |
| 108 | |
| 109 | Print very short usage message and exit. |
| 110 | |
| 111 | =item B<--verbose> |
| 112 | |
| 113 | Do print informational messages. |
| 114 | |
| 115 | =item B<--version> |
| 116 | |
| 117 | Print program version and exit. |
| 118 | |
| 119 | =item B<--quiet> |
| 120 | |
| 121 | Work 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 | |
| 133 | A name of executable or shared object to check. Multiple files may be specified. |
| 134 | |
| 135 | =back |
| 136 | |
| 137 | =head1 EXAMPLES |
| 138 | |
Jonathan Peyton | f0efbb5 | 2015-06-01 02:41:44 +0000 | [diff] [blame] | 139 | Check libomp.so library: |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 140 | |
Jonathan Peyton | f0efbb5 | 2015-06-01 02:41:44 +0000 | [diff] [blame] | 141 | $ check-execstack.pl libomp.so |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 142 | |
| 143 | =cut |
| 144 | |
| 145 | # end of file # |
| 146 | |