1#!/usr/bin/env python3 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 13import argparse 14import os 15import re 16import sys 17from libomputils import ScriptError, error, print_error_line, execute_command 18 19 20def is_stack_executable_readelf(library): 21 """Returns true if stack of library file is executable""" 22 r = execute_command(["readelf", "-l", "-W", library]) 23 if r.returncode != 0: 24 error("{} failed".format(r.command)) 25 stack_lines = [] 26 for line in r.stdout.split(os.linesep): 27 if re.search("STACK", line): 28 stack_lines.append(line.strip()) 29 if not stack_lines: 30 error("{}: Not stack segment found".format(library)) 31 if len(stack_lines) > 1: 32 error("{}: More than one stack segment found".format(library)) 33 h = r"0x[0-9a-fA-F]+" 34 m = re.search( 35 r"((GNU_)?STACK)\s+({0})\s+({0})\s+({0})\s+({0})\s+({0})" 36 " ([R ][W ][E ])".format(h), 37 stack_lines[0], 38 ) 39 if not m: 40 error("{}: Cannot parse stack segment line".format(library)) 41 if m: 42 flags = m.group(8) 43 if "E" in flags: 44 return True 45 return False 46 47 48def main(): 49 parser = argparse.ArgumentParser( 50 description="Check library does not have" " executable stack" 51 ) 52 parser.add_argument("library", help="The library file to check") 53 commandArgs = parser.parse_args() 54 if is_stack_executable_readelf(commandArgs.library): 55 error("{}: Stack is executable".format(commandArgs.library)) 56 57 58if __name__ == "__main__": 59 try: 60 main() 61 except ScriptError as e: 62 print_error_line(str(e)) 63 sys.exit(1) 64 65# end of file 66