Skip to content

Buffer overflow in create_file_hook_narrow: override written into the caller lpFileName buffer #105

Description

@HetCreep

What

create_file_hook_narrow writes the boot.config override path into the caller's lpFileName buffer via memcpy, which overflows that buffer whenever the override path is longer than the original path the game passed to CreateFileA.

Detail

src/windows/entrypoint.c (master 686e19b):

if (strcmpi(normalised_path, default_boot_config_path) == 0) {
    char *narrowed_boot_config_override = narrow(config.boot_config_override);
    memcpy(actual_file_name, narrowed_boot_config_override,
           strlen(config.boot_config_override));   // actual_file_name == caller's lpFileName
    free(narrowed_boot_config_override);
    ...
}
return CreateFileA(actual_file_name, ...);

actual_file_name is the caller's lpFileName. The caller sized that buffer for its own path (...\X_Data\boot.config); copying a longer boot_config_override into it is an out-of-bounds write into the game's memory. (strlen on the wide config.boot_config_override is also the wrong length unit.)

The wide variant create_file_hook does this correctly — it points actual_file_name at the override and never writes into the caller's buffer.

Fix

Mirror the wide hook: point actual_file_name at our own narrowed override buffer, pass it to CreateFileA, and free it after the call. No write into the caller's buffer. PR attached.

(Triggers on the ANSI CreateFileA path with boot_config_override set to a path longer than the game's boot.config path.)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions