146 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
| #!/usr/bin/perl
 | |
| 
 | |
| #
 | |
| #//===----------------------------------------------------------------------===//
 | |
| #//
 | |
| #// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| #// See https://llvm.org/LICENSE.txt for license information.
 | |
| #// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| #//
 | |
| #//===----------------------------------------------------------------------===//
 | |
| #
 | |
| 
 | |
| use strict;
 | |
| use warnings;
 | |
| 
 | |
| use FindBin;
 | |
| use lib "$FindBin::Bin/lib";
 | |
| 
 | |
| use tools;
 | |
| 
 | |
| our $VERSION = "0.002";
 | |
| my $target_arch;
 | |
| 
 | |
| sub execstack($) {
 | |
|     my ( $file ) = @_;
 | |
|     my @output;
 | |
|     my @stack;
 | |
|     my $tool;
 | |
|     if($target_arch eq "mic") {
 | |
|         $tool = "x86_64-k1om-linux-readelf";
 | |
|     } else {
 | |
|         $tool = "readelf";
 | |
|     }
 | |
|     execute( [ $tool, "-l", "-W", $file ], -stdout => \@output );
 | |
|     @stack = grep( $_ =~ m{\A\s*(?:GNU_)?STACK\s+}, @output );
 | |
|     if ( not @stack ) {
 | |
|         # Interpret missed "STACK" line as error.
 | |
|         runtime_error( "$file: No stack segment found; looks like stack would be executable." );
 | |
|     }; # if
 | |
|     if ( @stack > 1 ) {
 | |
|         runtime_error( "$file: More than one stack segment found.", "readelf output:", @output, "(eof)" );
 | |
|     }; # if
 | |
|     # Typical stack lines are:
 | |
|     # Linux* OS IA-32 architecture:
 | |
|     #    GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
 | |
|     # Linux* OS Intel(R) 64:
 | |
|     #    GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RWE 0x8
 | |
|     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} ) {
 | |
|         runtime_error( "$file: Cannot parse stack segment line:", ">>> $stack[ 0 ]" );
 | |
|     }; # if
 | |
|     my $attrs = $1;
 | |
|     if ( $attrs =~ m{E} ) {
 | |
|         runtime_error( "$file: Stack is executable" );
 | |
|     }; # if
 | |
| }; # sub execstack
 | |
| 
 | |
| get_options(
 | |
|     "arch=s" => \$target_arch,
 | |
| );
 | |
| 
 | |
| foreach my $file ( @ARGV ) {
 | |
|     execstack( $file );
 | |
| }; # foreach $file
 | |
| 
 | |
| exit( 0 );
 | |
| 
 | |
| __END__
 | |
| 
 | |
| =pod
 | |
| 
 | |
| =head1 NAME
 | |
| 
 | |
| B<check-execstack.pl> -- Check whether stack is executable, issue an error if so.
 | |
| 
 | |
| =head1 SYNOPSIS
 | |
| 
 | |
| B<check-execstack.pl> I<optiion>... I<file>...
 | |
| 
 | |
| =head1 DESCRIPTION
 | |
| 
 | |
| The script checks whether stack of specified executable file, and issues error if stack is
 | |
| executable. If stack is not executable, the script exits silently with zero exit code.
 | |
| 
 | |
| The script runs C<readelf> utility to get information about specified executable file. So, the
 | |
| script fails if C<readelf> is not available. Effectively it means the script works only on Linux* OS
 | |
| (and, probably, Intel(R) Many Integrated Core Architecture).
 | |
| 
 | |
| =head1 OPTIONS
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item Standard Options
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item B<--doc>
 | |
| 
 | |
| =item B<--manual>
 | |
| 
 | |
| Print full help message and exit.
 | |
| 
 | |
| =item B<--help>
 | |
| 
 | |
| Print short help message and exit.
 | |
| 
 | |
| =item B<--usage>
 | |
| 
 | |
| Print very short usage message and exit.
 | |
| 
 | |
| =item B<--verbose>
 | |
| 
 | |
| Do print informational messages.
 | |
| 
 | |
| =item B<--version>
 | |
| 
 | |
| Print program version and exit.
 | |
| 
 | |
| =item B<--quiet>
 | |
| 
 | |
| Work quiet, do not print informational messages.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 ARGUMENTS
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item I<file>
 | |
| 
 | |
| A name of executable or shared object to check. Multiple files may be specified.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 EXAMPLES
 | |
| 
 | |
| Check libomp.so library:
 | |
| 
 | |
|     $ check-execstack.pl libomp.so
 | |
| 
 | |
| =cut
 | |
| 
 | |
| # end of file #
 | |
| 
 |