glibc/scripts/check-wx-segment.py
Paul Eggert 581c785bf3 Update copyright dates with scripts/update-copyrights
I used these shell commands:

../glibc/scripts/update-copyrights $PWD/../gnulib/build-aux/update-copyright
(cd ../glibc && git commit -am"[this commit message]")

and then ignored the output, which consisted lines saying "FOO: warning:
copyright statement not found" for each of 7061 files FOO.

I then removed trailing white space from math/tgmath.h,
support/tst-support-open-dev-null-range.c, and
sysdeps/x86_64/multiarch/strlen-vec.S, to work around the following
obscure pre-commit check failure diagnostics from Savannah.  I don't
know why I run into these diagnostics whereas others evidently do not.

remote: *** 912-#endif
remote: *** 913:
remote: *** 914-
remote: *** error: lines with trailing whitespace found
...
remote: *** error: sysdeps/unix/sysv/linux/statx_cp.c: trailing lines
2022-01-01 11:40:24 -08:00

86 lines
2.8 KiB
Python

#!/usr/bin/python3
# Check ELF program headers for WX segments.
# Copyright (C) 2020-2022 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
#
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# The GNU C Library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with the GNU C Library; if not, see
# <https://www.gnu.org/licenses/>.
"""Check that the program headers do not contain write-exec segments."""
import argparse
import os.path
import re
import sys
# Regular expression to extract the RWE flags field. The
# address/offset columns have varying width.
RE_LOAD = re.compile(
r'^ LOAD +(?:0x[0-9a-fA-F]+ +){5}([R ][W ][ E]) +0x[0-9a-fA-F]+\n\Z')
def process_file(path, inp, xfail):
"""Analyze one input file."""
errors = 0
for line in inp:
error = None
if line.startswith(' LOAD '):
match = RE_LOAD.match(line)
if match is None:
error = 'Invalid LOAD line'
else:
flags, = match.groups()
if 'W' in flags and 'E' in flags:
if xfail:
print('{}: warning: WX segment (as expected)'.format(
path))
else:
error = 'WX segment'
if error is not None:
print('{}: error: {}: {!r}'.format(path, error, line.strip()))
errors += 1
if xfail and errors == 0:
print('{}: warning: missing expected WX segment'.format(path))
return errors
def main():
"""The main entry point."""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--xfail',
help='Mark input files as XFAILed ("*" for all)',
type=str, default='')
parser.add_argument('phdrs',
help='Files containing readelf -Wl output',
nargs='*')
opts = parser.parse_args(sys.argv)
xfails = set(opts.xfail.split(' '))
xfails_all = opts.xfail.strip() == '*'
errors = 0
for path in opts.phdrs:
xfail = ((os.path.basename(path) + '.phdrs') in xfails
or xfails_all)
with open(path) as inp:
errors += process_file(path, inp, xfail)
if errors > 0:
sys.exit(1)
if __name__ == '__main__':
main()