Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/3.1.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
William Roberts committed May 17, 2021
2 parents 2bae50a + 8240ebf commit 05beb08
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 150 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/)

## [3.1.0-rc2] - 2021-05-10
## [3.1.0] - 2021-05-17
### Fixed
- Fixed possible access outside the array in ifapi_calculate_tree.
- Fix CVE-2020-24455 FAPI PolicyPCR not instatiating correctly
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# All rights reserved.

AC_INIT([tpm2-tss],
[3.1.0-rc2],
[3.1.0],
[https://github.com/tpm2-software/tpm2-tss/issues],
[],
[https://github.com/tpm2-software/tpm2-tss])
Expand Down
165 changes: 98 additions & 67 deletions script/gen_fuzz.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@
import itertools

# Makefile-fuzz-generated.am is created from this template.
MAKEFILE_FUZZ = '''# SPDX-License-Identifier: BSD-2-Clause
MAKEFILE_FUZZ = """# SPDX-License-Identifier: BSD-2-Clause
# Copyright (c) 2018 Intel Corporation
# All rights reserved.
if ENABLE_TCTI_FUZZING
TESTS_FUZZ = %s
%s
endif # ENABLE_TCTI_FUZZING
'''
"""
# Each fuzz target in Makefile-fuzz-generated.am is created from this template.
MAKEFILE_FUZZ_TARGET = '''
MAKEFILE_FUZZ_TARGET = """
noinst_PROGRAMS += test/fuzz/%s.fuzz
test_fuzz_%s_fuzz_CPPFLAGS = $(FUZZ_CPPFLAGS)
test_fuzz_%s_fuzz_LDADD = $(FUZZLDADD)
nodist_test_fuzz_%s_fuzz_SOURCES = test/fuzz/main-sys.cpp \\
test/fuzz/%s.fuzz.cpp
DISTCLEANFILES += test/fuzz/%s.fuzz.cpp'''
DISTCLEANFILES += test/fuzz/%s.fuzz.cpp"""
# Common include definitions needed for fuzzing an SYS call
SYS_TEMPLATE_HEADER = '''/* SPDX-License-Identifier: BSD-2-Clause */
SYS_TEMPLATE_HEADER = """/* SPDX-License-Identifier: BSD-2-Clause */
/***********************************************************************
* Copyright (c) 2018, Intel Corporation
*
Expand Down Expand Up @@ -64,17 +64,22 @@
extern "C"
int
test_invoke (
TSS2_SYS_CONTEXT *sysContext)'''
TSS2_SYS_CONTEXT *sysContext)"""
# Template to call a SYS _Complete function which takes no arguments
SYS_COMPLETE_TEMPLATE_NO_ARGS = SYS_TEMPLATE_HEADER + '''
SYS_COMPLETE_TEMPLATE_NO_ARGS = (
SYS_TEMPLATE_HEADER
+ """
{
%s (sysContext);
return EXIT_SUCCESS;
}
'''
"""
)
# Template to call a SYS _Complete function which takes arguments
SYS_COMPLETE_TEMPLATE_HAS_ARGS = SYS_TEMPLATE_HEADER + '''
SYS_COMPLETE_TEMPLATE_HAS_ARGS = (
SYS_TEMPLATE_HEADER
+ """
{
%s
Expand All @@ -85,9 +90,12 @@
return EXIT_SUCCESS;
}
'''
"""
)
# Template to call a SYS _Prepare function
SYS_PREPARE_TEMPLATE_HAS_ARGS = SYS_TEMPLATE_HEADER + '''
SYS_PREPARE_TEMPLATE_HAS_ARGS = (
SYS_TEMPLATE_HEADER
+ """
{
int ret;
%s
Expand All @@ -108,101 +116,114 @@
return EXIT_SUCCESS;
}
'''
"""
)


def gen_file(function):
'''
"""
Generate a cpp file used as the fuzz target given the function definition
from a header file.
'''
"""
# Parse the function name from the function definition
function_name = function.split('\n')[0]\
.replace('TSS2_RC', '')\
.replace('(', '')\
.strip()
function_name = (
function.split("\n")[0].replace("TSS2_RC", "").replace("(", "").strip()
)
# Parse the function arguments into an array. Do not include sysContext.
args = [arg.strip() \
for arg in function[function.index('(') + 1:function.index(');')]\
.split(',') \
if not 'TSS2_SYS_CONTEXT' in arg]
args = [
arg.strip()
for arg in function[function.index("(") + 1 : function.index(");")].split(",")
if not "TSS2_SYS_CONTEXT" in arg
]
# Prepare and Complete functions require different methods of generation.
# Call the appropriate function to generate a cpp target specific to that
# type of function.
if '_Complete' in function_name:
if "_Complete" in function_name:
return gen_complete(function, function_name, args)
if '_Prepare' in function_name:
if "_Prepare" in function_name:
return gen_prepare(function, function_name, args)
raise NotImplementedError('Unknown function type %r' % (function_name,))
raise NotImplementedError("Unknown function type %r" % (function_name,))


def gen_complete(function, function_name, args):
'''
"""
Generate the cpp fuzz target for a SYS _Complete call
'''
"""
if not args:
# Fill in the no args template. Simple case.
return function_name, SYS_COMPLETE_TEMPLATE_NO_ARGS % (function_name)
# Generate the cpp variable definitions.
arg_definitions = (';\n' + ' ' * 4).join([
arg.replace('*', '') for arg in args]) + ';'
arg_definitions = (";\n" + " " * 4).join(
[arg.replace("*", "") for arg in args]
) + ";"
# Generate the cpp arguments. For arguments that are pointers find replace *
# with & so that we pass a pointer to the definition which has been
# allocated on the stack.
arg_call = (',\n' + ' ' * 8).join([
arg.replace('*', '&').split()[-1] for arg in args])
arg_call = (",\n" + " " * 8).join(
[arg.replace("*", "&").split()[-1] for arg in args]
)
# Fill in the template
return function_name, SYS_COMPLETE_TEMPLATE_HAS_ARGS % (arg_definitions,
function_name,
arg_call)
return (
function_name,
SYS_COMPLETE_TEMPLATE_HAS_ARGS % (arg_definitions, function_name, arg_call),
)


def gen_prepare(function, function_name, args):
'''
"""
Generate the cpp fuzz target for a SYS _Prepare call
'''
"""
if not args:
return function_name, None
# Generate the cpp variable definitions. Make sure to initialize to empty
# structs (works for initializing anything) or cpp compiler will complain.
arg_definitions = (' = {0};\n' + ' ' * 4).join([
arg.replace('*', '').replace('const', '') for arg in args]) + ' = {0};'
arg_definitions = (" = {0};\n" + " " * 4).join(
[arg.replace("*", "").replace("const", "") for arg in args]
) + " = {0};"
# Generate the cpp arguments. For arguments that are pointers find replace *
# with & so that we pass a pointer to the definition which has been
# allocated on the stack.
arg_call = (',\n' + ' ' * 8).join([
arg.replace('*', '&').split()[-1] for arg in args])
arg_call = (",\n" + " " * 8).join(
[arg.replace("*", "&").split()[-1] for arg in args]
)
# Generate the call to fuzz_fill. The call should be the sysContext, double
# the number of arguments for the _Prepare call, and then for each _Prepare
# argument pass two to fuzz_fill, the sizeof the _Prepare argument, and a
# pointer to it.
fill_fuzz_args = (',\n' + ' ' * 8).join([
('sizeof (%s), &%s' % \
tuple([arg.replace('*', '').split()[-1]] * 2)) \
for arg in args])
fill_fuzz_args = (",\n" + " " * 8).join(
[
("sizeof (%s), &%s" % tuple([arg.replace("*", "").split()[-1]] * 2))
for arg in args
]
)
# Fill in the template
return function_name, SYS_PREPARE_TEMPLATE_HAS_ARGS % (arg_definitions,
len(args) * 2,
fill_fuzz_args,
function_name,
arg_call)
return (
function_name,
SYS_PREPARE_TEMPLATE_HAS_ARGS
% (arg_definitions, len(args) * 2, fill_fuzz_args, function_name, arg_call),
)


def functions_from_include(header):
'''
"""
Parse out and yield each function definition from a header file.
'''
with open(header, 'r') as header_fd:
current_function = ''
"""
with open(header, "r") as header_fd:
current_function = ""
for line in header_fd:
# Functions we are interested in start with _Complete or _Prepare
if '_Complete' in line or '_Prepare' in line:
if "_Complete" in line or "_Prepare" in line:
# Set the current_function to this line
current_function = line
elif current_function and ');' in line:
elif current_function and ");" in line:
# When we reach the closing parenthesis yield the function
yield current_function + line.rstrip()
current_function = ''
current_function = ""
elif current_function:
# Add all the arguments to the function
current_function += line


def gen_files(header):
# Generate a fuzz target cpp file from each function in the header file
for current_function in functions_from_include(header):
Expand All @@ -213,28 +234,38 @@ def gen_files(header):
# Yield the function name and the contents of its generated file
yield function_name, contents


def main():
parser = argparse.ArgumentParser(description='Generate libfuzzer for sys')
parser.add_argument('--header', default='include/tss2/tss2_sys.h',
help='Header file to look in (default include/tss2/tss2_sys.h)')
parser = argparse.ArgumentParser(description="Generate libfuzzer for sys")
parser.add_argument(
"--header",
default="include/tss2/tss2_sys.h",
help="Header file to look in (default include/tss2/tss2_sys.h)",
)
args = parser.parse_args()

functions = dict(gen_files(args.header))
# Write the generated target to the file for its function name
for function_name, contents in functions.items():
filepath = os.path.join('test', 'fuzz', function_name + '.fuzz.cpp')
with open(filepath, 'w') as fuzzer_fd:
filepath = os.path.join("test", "fuzz", function_name + ".fuzz.cpp")
with open(filepath, "w") as fuzzer_fd:
fuzzer_fd.write(contents)
# Fill in the Makefile-fuzz-generated.am template using the function names.
# Create a list of the compiled fuzz targets
files = ' \\\n '.join(['test/fuzz/%s.fuzz' % (function) \
for function in functions])
files = " \\\n ".join(
["test/fuzz/%s.fuzz" % (function) for function in functions]
)
# Create the Makefile targets for each generated file
targets = '\n'.join([MAKEFILE_FUZZ_TARGET % tuple(list(itertools.chain(\
([function] * 6)))) for function in functions])
targets = "\n".join(
[
MAKEFILE_FUZZ_TARGET % tuple(list(itertools.chain(([function] * 6))))
for function in functions
]
)
# Write out the Makefile-fuzz-generated.am file
with open('Makefile-fuzz-generated.am', 'w') as makefile_fd:
with open("Makefile-fuzz-generated.am", "w") as makefile_fd:
makefile_fd.write(MAKEFILE_FUZZ % (files, targets))

if __name__ == '__main__':

if __name__ == "__main__":
main()
Loading

0 comments on commit 05beb08

Please sign in to comment.