1*88dae3d5SJonathan Peyton#!/usr/bin/env python3 2*88dae3d5SJonathan Peyton 3*88dae3d5SJonathan Peyton# 4*88dae3d5SJonathan Peyton# //===----------------------------------------------------------------------===// 5*88dae3d5SJonathan Peyton# // 6*88dae3d5SJonathan Peyton# // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 7*88dae3d5SJonathan Peyton# // See https://llvm.org/LICENSE.txt for license information. 8*88dae3d5SJonathan Peyton# // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 9*88dae3d5SJonathan Peyton# // 10*88dae3d5SJonathan Peyton# //===----------------------------------------------------------------------===// 11*88dae3d5SJonathan Peyton# 12*88dae3d5SJonathan Peyton 13*88dae3d5SJonathan Peytonimport argparse 14*88dae3d5SJonathan Peytonimport os 15*88dae3d5SJonathan Peytonimport re 16*88dae3d5SJonathan Peytonimport sys 17*88dae3d5SJonathan Peytonfrom libomputils import ScriptError, error, print_error_line, execute_command 18*88dae3d5SJonathan Peyton 19*88dae3d5SJonathan Peyton 20*88dae3d5SJonathan Peytondef is_stack_executable_readelf(library): 21*88dae3d5SJonathan Peyton """Returns true if stack of library file is executable""" 22*88dae3d5SJonathan Peyton r = execute_command(["readelf", "-l", "-W", library]) 23*88dae3d5SJonathan Peyton if r.returncode != 0: 24*88dae3d5SJonathan Peyton error("{} failed".format(r.command)) 25*88dae3d5SJonathan Peyton stack_lines = [] 26*88dae3d5SJonathan Peyton for line in r.stdout.split(os.linesep): 27*88dae3d5SJonathan Peyton if re.search("STACK", line): 28*88dae3d5SJonathan Peyton stack_lines.append(line.strip()) 29*88dae3d5SJonathan Peyton if not stack_lines: 30*88dae3d5SJonathan Peyton error("{}: Not stack segment found".format(library)) 31*88dae3d5SJonathan Peyton if len(stack_lines) > 1: 32*88dae3d5SJonathan Peyton error("{}: More than one stack segment found".format(library)) 33*88dae3d5SJonathan Peyton h = r"0x[0-9a-fA-F]+" 34*88dae3d5SJonathan Peyton m = re.search( 35*88dae3d5SJonathan Peyton r"((GNU_)?STACK)\s+({0})\s+({0})\s+({0})\s+({0})\s+({0})" 36*88dae3d5SJonathan Peyton " ([R ][W ][E ])".format(h), 37*88dae3d5SJonathan Peyton stack_lines[0], 38*88dae3d5SJonathan Peyton ) 39*88dae3d5SJonathan Peyton if not m: 40*88dae3d5SJonathan Peyton error("{}: Cannot parse stack segment line".format(library)) 41*88dae3d5SJonathan Peyton if m: 42*88dae3d5SJonathan Peyton flags = m.group(8) 43*88dae3d5SJonathan Peyton if "E" in flags: 44*88dae3d5SJonathan Peyton return True 45*88dae3d5SJonathan Peyton return False 46*88dae3d5SJonathan Peyton 47*88dae3d5SJonathan Peyton 48*88dae3d5SJonathan Peytondef main(): 49*88dae3d5SJonathan Peyton parser = argparse.ArgumentParser( 50*88dae3d5SJonathan Peyton description="Check library does not have" " executable stack" 51*88dae3d5SJonathan Peyton ) 52*88dae3d5SJonathan Peyton parser.add_argument("library", help="The library file to check") 53*88dae3d5SJonathan Peyton commandArgs = parser.parse_args() 54*88dae3d5SJonathan Peyton if is_stack_executable_readelf(commandArgs.library): 55*88dae3d5SJonathan Peyton error("{}: Stack is executable".format(commandArgs.library)) 56*88dae3d5SJonathan Peyton 57*88dae3d5SJonathan Peyton 58*88dae3d5SJonathan Peytonif __name__ == "__main__": 59*88dae3d5SJonathan Peyton try: 60*88dae3d5SJonathan Peyton main() 61*88dae3d5SJonathan Peyton except ScriptError as e: 62*88dae3d5SJonathan Peyton print_error_line(str(e)) 63*88dae3d5SJonathan Peyton sys.exit(1) 64*88dae3d5SJonathan Peyton 65*88dae3d5SJonathan Peyton# end of file 66