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