Loading...
--- Libc/Libc-1725.40.4/tests/fortify_source/fortify_source.py
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/env python3
-"""
-test_fortify_source.py
-
-This verifies that when _FORTIFY_SOURCE is enabled, the appropriate functions
-get defined to a _chk or _ptrchk variant (and if necessary, that the size is
-queried with the right kind of __builtin_object_size invocation).
-
-IF YOU ARE ADDING A CHECKED VARIANT FOR A FUNCTION:
-After adding your variant, run this script with -g to generate the new expected
-normal. Replace expected values in the PARAMETERS arrays with what you get.
-
-IF YOU ARE ADDING A NEW CONDITIONAL MODE:
-If you conditionally add a checked variant based on a C version or POSIX
-standard version, make sure that there is a TestParameters entry that covers the
-case where you expect the builtin to be used and at least one case where it is
-not. Add entries as needed.
-
-Run the script at desk with:
-
-% python3 fortify_source.py --verbose --check-syntax --include-dir $(DSTROOT)/usr/include fortify_source.c
-
-Don't forget to test with each SDK variant (ie, Darwin userspace, DriverKit, etc).
-"""
-from argparse import ArgumentParser
-from collections import namedtuple
-import os
-import re
-import subprocess
-import sys
-
-BADFUNC = "BADFUNC"
-UNDEFINED = "UNDEFINED"
-BUILTIN_OBSZ = "BUILTIN_OBSZ"
-BUILTIN_OBSZ0 = "BUILTIN_OBSZ0"
-PTRCHECK_OBSZ = "PTRCHECK_OBSZ"
-PTRCHECK_OBSZ0 = "PTRCHECK_OBSZ0"
-
-TestParameters = namedtuple(typename="TestParameters", field_names=["posix_c_source", "darwin_c_level", "fbounds_safety", "expected_driverkit", "expected_userspace"])
-
-PARAMETERS = [
- TestParameters(posix_c_source=None, darwin_c_level=0, fbounds_safety=None,
- expected_driverkit={"bcopy": UNDEFINED, "bzero": UNDEFINED, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": UNDEFINED, "sprintf": UNDEFINED, "stpcpy": UNDEFINED, "stpncpy": UNDEFINED, "strcat": UNDEFINED, "strcpy": UNDEFINED, "strlcat": UNDEFINED, "strlcpy": UNDEFINED, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": UNDEFINED, "vsprintf": UNDEFINED, },
- expected_userspace={"bcopy": UNDEFINED, "bzero": UNDEFINED, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": UNDEFINED, "sprintf": BUILTIN_OBSZ0, "stpcpy": UNDEFINED, "stpncpy": UNDEFINED, "strcat": BUILTIN_OBSZ0, "strcpy": BUILTIN_OBSZ0, "strlcat": UNDEFINED, "strlcpy": UNDEFINED, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": UNDEFINED, "vsprintf": UNDEFINED, },),
-
- TestParameters(posix_c_source=None, darwin_c_level="200112", fbounds_safety=None,
- expected_driverkit={"bcopy": UNDEFINED, "bzero": UNDEFINED, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": BUILTIN_OBSZ0, "sprintf": UNDEFINED, "stpcpy": UNDEFINED, "stpncpy": UNDEFINED, "strcat": UNDEFINED, "strcpy": UNDEFINED, "strlcat": UNDEFINED, "strlcpy": UNDEFINED, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": BUILTIN_OBSZ0, "vsprintf": UNDEFINED, },
- expected_userspace={"bcopy": UNDEFINED, "bzero": UNDEFINED, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": BUILTIN_OBSZ0, "sprintf": BUILTIN_OBSZ0, "stpcpy": UNDEFINED, "stpncpy": UNDEFINED, "strcat": BUILTIN_OBSZ0, "strcpy": BUILTIN_OBSZ0, "strlcat": UNDEFINED, "strlcpy": UNDEFINED, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": BUILTIN_OBSZ0, "vsprintf": BUILTIN_OBSZ0, },),
-
- TestParameters(posix_c_source=None, darwin_c_level="200809", fbounds_safety=None,
- expected_driverkit={"bcopy": UNDEFINED, "bzero": UNDEFINED, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": BUILTIN_OBSZ0, "sprintf": UNDEFINED, "stpcpy": UNDEFINED, "stpncpy": BUILTIN_OBSZ0, "strcat": UNDEFINED, "strcpy": UNDEFINED, "strlcat": UNDEFINED, "strlcpy": UNDEFINED, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": BUILTIN_OBSZ0, "vsprintf": UNDEFINED, },
- expected_userspace={"bcopy": UNDEFINED, "bzero": UNDEFINED, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": BUILTIN_OBSZ0, "sprintf": BUILTIN_OBSZ0, "stpcpy": BUILTIN_OBSZ0, "stpncpy": BUILTIN_OBSZ0, "strcat": BUILTIN_OBSZ0, "strcpy": BUILTIN_OBSZ0, "strlcat": UNDEFINED, "strlcpy": UNDEFINED, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": BUILTIN_OBSZ0, "vsprintf": BUILTIN_OBSZ0, },),
-
- TestParameters(posix_c_source=None, darwin_c_level="__DARWIN_C_FULL", fbounds_safety=None,
- expected_driverkit={"bcopy": BUILTIN_OBSZ, "bzero": BUILTIN_OBSZ, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": BUILTIN_OBSZ0, "sprintf": UNDEFINED, "stpcpy": UNDEFINED, "stpncpy": BUILTIN_OBSZ0, "strcat": UNDEFINED, "strcpy": UNDEFINED, "strlcat": BUILTIN_OBSZ0, "strlcpy": BUILTIN_OBSZ0, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": BUILTIN_OBSZ0, "vsprintf": UNDEFINED, },
- expected_userspace={"bcopy": BUILTIN_OBSZ, "bzero": BUILTIN_OBSZ, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": BUILTIN_OBSZ0, "sprintf": BUILTIN_OBSZ0, "stpcpy": BUILTIN_OBSZ0, "stpncpy": BUILTIN_OBSZ0, "strcat": BUILTIN_OBSZ0, "strcpy": BUILTIN_OBSZ0, "strlcat": BUILTIN_OBSZ0, "strlcpy": BUILTIN_OBSZ0, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": BUILTIN_OBSZ0, "vsprintf": BUILTIN_OBSZ0, },),
-
- TestParameters(posix_c_source="0", darwin_c_level="__DARWIN_C_FULL", fbounds_safety=None,
- expected_driverkit={"bcopy": BUILTIN_OBSZ, "bzero": BUILTIN_OBSZ, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": BUILTIN_OBSZ0, "sprintf": UNDEFINED, "stpcpy": UNDEFINED, "stpncpy": BUILTIN_OBSZ0, "strcat": UNDEFINED, "strcpy": UNDEFINED, "strlcat": BUILTIN_OBSZ0, "strlcpy": BUILTIN_OBSZ0, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": BUILTIN_OBSZ0, "vsprintf": UNDEFINED, },
- expected_userspace={"bcopy": BUILTIN_OBSZ, "bzero": BUILTIN_OBSZ, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": BUILTIN_OBSZ0, "sprintf": BUILTIN_OBSZ0, "stpcpy": BUILTIN_OBSZ0, "stpncpy": BUILTIN_OBSZ0, "strcat": BUILTIN_OBSZ0, "strcpy": BUILTIN_OBSZ0, "strlcat": BUILTIN_OBSZ0, "strlcpy": BUILTIN_OBSZ0, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": BUILTIN_OBSZ0, "vsprintf": BUILTIN_OBSZ0, },),
-
- TestParameters(posix_c_source=None, darwin_c_level="__DARWIN_C_FULL", fbounds_safety=None,
- expected_driverkit={"bcopy": BUILTIN_OBSZ, "bzero": BUILTIN_OBSZ, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": BUILTIN_OBSZ0, "sprintf": UNDEFINED, "stpcpy": UNDEFINED, "stpncpy": BUILTIN_OBSZ0, "strcat": UNDEFINED, "strcpy": UNDEFINED, "strlcat": BUILTIN_OBSZ0, "strlcpy": BUILTIN_OBSZ0, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": BUILTIN_OBSZ0, "vsprintf": UNDEFINED, },
- expected_userspace={"bcopy": BUILTIN_OBSZ, "bzero": BUILTIN_OBSZ, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": BUILTIN_OBSZ0, "sprintf": BUILTIN_OBSZ0, "stpcpy": BUILTIN_OBSZ0, "stpncpy": BUILTIN_OBSZ0, "strcat": BUILTIN_OBSZ0, "strcpy": BUILTIN_OBSZ0, "strlcat": BUILTIN_OBSZ0, "strlcpy": BUILTIN_OBSZ0, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": BUILTIN_OBSZ0, "vsprintf": BUILTIN_OBSZ0, },),
-
- TestParameters(posix_c_source=None, darwin_c_level="__DARWIN_C_FULL", fbounds_safety="on",
- expected_driverkit={"bcopy": BUILTIN_OBSZ, "bzero": BUILTIN_OBSZ, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": BUILTIN_OBSZ0, "sprintf": UNDEFINED, "stpcpy": UNDEFINED, "stpncpy": BUILTIN_OBSZ0, "strcat": UNDEFINED, "strcpy": UNDEFINED, "strlcat": BUILTIN_OBSZ0, "strlcpy": BUILTIN_OBSZ0, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": BUILTIN_OBSZ0, "vsprintf": UNDEFINED, },
- expected_userspace={"bcopy": BUILTIN_OBSZ, "bzero": BUILTIN_OBSZ, "memccpy": BUILTIN_OBSZ, "memmove": BUILTIN_OBSZ, "memcpy": BUILTIN_OBSZ, "memset": BUILTIN_OBSZ, "snprintf": BUILTIN_OBSZ0, "sprintf": BUILTIN_OBSZ0, "stpcpy": BUILTIN_OBSZ0, "stpncpy": BUILTIN_OBSZ0, "strcat": BUILTIN_OBSZ0, "strcpy": BUILTIN_OBSZ0, "strlcat": BUILTIN_OBSZ0, "strlcpy": BUILTIN_OBSZ0, "strncat": BUILTIN_OBSZ0, "strncpy": BUILTIN_OBSZ0, "vsnprintf": BUILTIN_OBSZ0, "vsprintf": BUILTIN_OBSZ0, },),
-
- TestParameters(posix_c_source=None, darwin_c_level="__DARWIN_C_FULL", fbounds_safety="on_attributes",
- expected_driverkit={"bcopy": PTRCHECK_OBSZ, "bzero": PTRCHECK_OBSZ, "memccpy": PTRCHECK_OBSZ, "memmove": PTRCHECK_OBSZ, "memcpy": PTRCHECK_OBSZ, "memset": PTRCHECK_OBSZ, "snprintf": PTRCHECK_OBSZ0, "sprintf": UNDEFINED, "stpcpy": UNDEFINED, "stpncpy": UNDEFINED, "strcat": UNDEFINED, "strcpy": UNDEFINED, "strlcat": PTRCHECK_OBSZ, "strlcpy": PTRCHECK_OBSZ, "strncat": PTRCHECK_OBSZ, "strncpy": UNDEFINED, "vsnprintf": PTRCHECK_OBSZ0, "vsprintf": UNDEFINED, },
- expected_userspace={"bcopy": PTRCHECK_OBSZ, "bzero": PTRCHECK_OBSZ, "memccpy": PTRCHECK_OBSZ, "memmove": PTRCHECK_OBSZ, "memcpy": PTRCHECK_OBSZ, "memset": PTRCHECK_OBSZ, "snprintf": PTRCHECK_OBSZ0, "sprintf": UNDEFINED, "stpcpy": UNDEFINED, "stpncpy": UNDEFINED, "strcat": UNDEFINED, "strcpy": UNDEFINED, "strlcat": PTRCHECK_OBSZ, "strlcpy": PTRCHECK_OBSZ, "strncat": UNDEFINED, "strncpy": UNDEFINED, "vsnprintf": PTRCHECK_OBSZ0, "vsprintf": UNDEFINED, },),
-]
-
-
-def parse_substitution_dictionary(stream):
- test_line_re = re.compile(rb"^test_(\w+):\s*([^(;\s]*).*$")
- result = {}
- for line in stream:
- m = test_line_re.match(line)
- if not m:
- continue
- key = m.group(1).decode("ASCII")
- if m.group(2) == b"undefined":
- result[key] = UNDEFINED
- continue
-
- # for all substitutions except bcopy/bzero (which boil down to memcpy/memset),
- # we check that the result line contains the right function name
- colon = line.index(b":") + 1
- if line.find(b"_" + m.group(1) + b"_", colon) == -1:
- if key not in ["bcopy", "bzero"]:
- result[key] = BADFUNC
- continue
-
- if m.group(2) == "":
- if "__libc_ptrchk_strbuf_chk" in line:
- result[key] = PTRCHECK_OBSZ
- else:
- builtin = b"__builtin" in m.group(2)
- obsz = False
- idx = line.find(b"__builtin_object_size")
- if idx != -1:
- open = line.index(b",", idx) + 1
- close = line.find(b")", open)
- obsz = line[open:close].strip() != b"0"
-
- if (builtin, obsz) == (True, True):
- result[key] = BUILTIN_OBSZ0
- elif (builtin, obsz) == (True, False):
- result[key] = BUILTIN_OBSZ
- elif (builtin, obsz) == (False, True):
- result[key] = PTRCHECK_OBSZ0
- elif (builtin, obsz) == (False, False):
- result[key] = PTRCHECK_OBSZ
- return result
-
-
-def print_substitution_dictionary(d):
- print("{", end="")
- for k in sorted(d.keys()):
- print('"%s": %s, ' % (k, d[k]), end="")
- print("},")
-
-
-def main():
- parser = ArgumentParser(description="test that bounds-sensitive functions have _chk substitutions")
- parser.add_argument("test_file", default="./fortify_source.c", help="file to preprocess")
- parser.add_argument("--sdk", default=os.getenv("SDKROOT"), help="SDK to test for (defaults to $SDKROOT)")
- parser.add_argument("-g", "--generate", action="store_true", help="print observed output instead of comparing it with desired output")
- parser.add_argument("-I", "--include-dir", action="append", default=[], help="Additional include paths (you can point this to the usr/include of a libc root)")
- parser.add_argument("-v", "--verbose", action="store_true", help="Print clang commands that are executed")
- parser.add_argument("-s", "--check-syntax", action="store_true", help="Also run clang with -fsyntax-only to check that this actually builds")
- arguments = parser.parse_args()
- if arguments.sdk is None:
- sys.stderr.write("*** $SDKROOT is not set\n")
- sys.exit(1)
-
- is_driverkit = "driverkit" in arguments.sdk.lower()
-
- def verbose_print(value):
- if arguments.verbose:
- print(" ".join(value))
- return value
-
- failed = False
- for (posix_c_source, darwin_c_level, fbounds_safety, expected_dk, expected_us) in PARAMETERS:
- clang_args = [
- "xcrun", "--sdk", arguments.sdk, "clang", "-Werror", "-D_FORTIFY_SOURCE=2", arguments.test_file]
- for inc in arguments.include_dir:
- clang_args.append("-isystem")
- clang_args.append(inc)
- if posix_c_source is not None:
- clang_args.append("-D_TEST_POSIX_C_SOURCE=%s" % posix_c_source)
- if darwin_c_level is not None:
- clang_args.append("-D_TEST_DARWIN_C_LEVEL=%s" % darwin_c_level)
- if fbounds_safety == "on":
- clang_args.append("-fbounds-safety")
- clang_args.append("-DUNDEF_BOUNDS_SAFETY_ATTRIBUTES")
- elif fbounds_safety == "on_attributes":
- clang_args.append("-fbounds-safety")
- clang_args.append("-D__LIBC_STAGED_BOUNDS_SAFETY_ATTRIBUTES")
-
- if arguments.check_syntax:
- syntax_check = list(clang_args)
- syntax_check.extend(("-fsyntax-only", "-Wno-nullability-completeness"))
- subprocess.check_call(verbose_print(syntax_check))
-
- clang_args.extend(("-E", "-o", "-"))
- p = subprocess.Popen(verbose_print(clang_args), stdin=subprocess.DEVNULL, stdout=subprocess.PIPE)
-
- d = parse_substitution_dictionary(p.stdout)
- p.wait()
- if arguments.generate:
- print_substitution_dictionary(d)
- continue
-
- expected = expected_dk if is_driverkit else expected_us
- if d == expected:
- continue
-
- failed = True
- params = []
- params.append("_POSIX_C_SOURCE=%r" % posix_c_source)
- params.append("__DARWIN_C_LEVEL=%r" % darwin_c_level)
- params.append("-f%sbounds-safety" % ("" if fbounds_safety else "no"))
- if fbounds_safety:
- params.append("-%s__LIBC_STAGED_BOUNDS_SAFETY_ATTRIBUTES" % ("D" if fbounds_safety == "on_attributes" else "U"))
- print("*** FAILED: " + ", ".join(params))
- for k in sorted(d.keys()):
- if k not in expected:
- print("*** %s is %s (missing in expected dictionary)" % (k, d[k]))
- elif d[k] != expected[k]:
- print("*** %s is %s (expected: %s)" % (k, d[k], expected[k]))
- for k in sorted(expected.keys()):
- if k not in d:
- print("*** %s is missing (expected: %s)" % (k, expected[k]))
-
- sys.exit(1 if failed else 0)
-
-
-if __name__ == "__main__":
- main()