Skip to content

Add graceful handling of expected exceptions in fuzz_submodule.py #1922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Improve file name generation to prevent "File name too long" OSError's
Adds a utility function to limit the maximum file name legnth produced
by the fuzzer to a max size dictated by the host its run on.
  • Loading branch information
DaveLak committed May 30, 2024
commit 6c00ce602eb19eda342e827a25d005610ce92fa8
13 changes: 6 additions & 7 deletions fuzzing/fuzz-targets/fuzz_submodule.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import os
import tempfile
from configparser import ParsingError
from utils import is_expected_exception_message
from utils import is_expected_exception_message, get_max_filename_length

if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
path_to_bundled_git_binary = os.path.abspath(os.path.join(os.path.dirname(__file__), "git"))
Expand Down Expand Up @@ -42,12 +42,12 @@ def TestOneInput(data):
writer.release()

submodule.update(init=fdp.ConsumeBool(), dry_run=fdp.ConsumeBool(), force=fdp.ConsumeBool())

submodule_repo = submodule.module()
new_file_path = os.path.join(
submodule_repo.working_tree_dir,
f"new_file_{fdp.ConsumeUnicodeNoSurrogates(fdp.ConsumeIntInRange(1, 512))}",

new_file_name = fdp.ConsumeUnicodeNoSurrogates(
fdp.ConsumeIntInRange(1, max(1, get_max_filename_length(submodule_repo.working_tree_dir)))
)
new_file_path = os.path.join(submodule_repo.working_tree_dir, new_file_name)
with open(new_file_path, "wb") as new_file:
new_file.write(fdp.ConsumeBytes(fdp.ConsumeIntInRange(1, 512)))
submodule_repo.index.add([new_file_path])
Expand Down Expand Up @@ -77,14 +77,13 @@ def TestOneInput(data):
BrokenPipeError,
):
return -1
except (ValueError, OSError) as e:
except ValueError as e:
expected_messages = [
"SHA is empty",
"Reference at",
"embedded null byte",
"This submodule instance does not exist anymore",
"cmd stdin was empty",
"File name too long",
]
if is_expected_exception_message(e, expected_messages):
return -1
Expand Down
15 changes: 15 additions & 0 deletions fuzzing/fuzz-targets/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import atheris # pragma: no cover
import os
from typing import List # pragma: no cover


Expand All @@ -20,3 +21,17 @@ def is_expected_exception_message(exception: Exception, error_message_list: List
if error.lower() in exception_message:
return True
return False


@atheris.instrument_func
def get_max_filename_length(path: str) -> int:
"""
Get the maximum filename length for the filesystem containing the given path.

Args:
path (str): The path to check the filesystem for.

Returns:
int: The maximum filename length.
"""
return os.pathconf(path, "PC_NAME_MAX")