mirror of
https://github.com/google/brotli.git
synced 2026-07-08 17:56:58 +00:00
CloseFiles() previously called fclose(context->fout) before invoking CopyStat() on the output pathname. CopyStat() then used path-based chmod() and chown(), which gave an attacker with write access to the output directory a window to replace the path with a symlink between the close and the metadata syscalls, redirecting the chmod/chown to an arbitrary target. Close the race by doing the metadata copy while the output file is still open and by switching to fd-based syscalls on fileno(fout): - CopyStat() now takes FILE* fout and calls fchmod()/fchown() on the underlying fd. - CopyTimeStat() uses futimens(fd, ...) in the HAVE_UTIMENSAT branch; the legacy utime() fallback is preserved for platforms without it. - CloseFiles() invokes CopyStat() before fclose() and skips it when current_output_path is NULL (stdout), matching the issue's guidance. - Windows no-op shims updated from chmod/chown to fchmod/fchown. Adds deterministic regression coverage under tests/regression/t01/: an LD_PRELOAD fclose() swap reproduces the pre-fix behavior, and a negative-assertion wrapper confirms the attack no longer succeeds after the patch. Additional scripts cover mode/timestamp propagation, the -n (no-copy-stat) flag, stdin input, stdout output, mode mask, and roundtrip correctness. Refs google/brotli#1461