TOCTOU race condition in grabbag__file_copy_metadata()
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 2.4k
- Forks
- 363
- PR merge metrics
- No merged PRs in 30d
Description
TOCTOU race condition in grabbag__file_copy_metadata()
Environment
- flac version: 1.3.3
- OS: Ubuntu 22.04 (WSL)
- Tool: strace 5.16
Summary
grabbag__file_copy_metadata() in src/share/grabbag/file.c:116 calls
flac_stat(filename) and flac_chmod(filename) on the same path string.
Between the two calls, a local attacker with write access to the output
directory can atomically replace the file with a symlink pointing to an
arbitrary target. The subsequent chmod() follows the symlink and changes
permissions on that target.
Vulnerable pattern
// src/share/grabbag/file.c
flac_stat(filename, &stats); // CHECK: read mode by path
flac_chmod(filename, stats.st_mode); // USE: apply mode by path
Verification
strace confirms chmod() is called by path, not fchmod() by descriptor:
chmod("/tmp/.../dst.flac", 0100644) = 0 // by path — vulnerable
// fchmod() not observed
Race confirmed with a PoC script (written with AI assistance):
- symlink swap succeeded on attempt 4 out of 50,000
- victim file permissions changed from 000 to 644
- tested on flac 1.3.3, Ubuntu/WSL
Attack scenario
Most relevant when flac is invoked by a service or automated pipeline
with elevated privileges, where the output directory is also writable by
a lower-privileged user (e.g. media processing server, NAS, CI/CD pipeline).
Suggested fix
Replace path-based calls with file-descriptor-based equivalents:
// BEFORE
flac_stat(filename, &stats);
flac_chmod(filename, stats.st_mode);
// AFTER
int fd = open(filename, O_RDONLY);
if (fd >= 0) {
fstat(fd, &stats);
fchmod(fd, stats.st_mode);
close(fd);
}
Note
PoC script available on request.
Reported by: Luong Trieu Dai
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/share/grabbag/file.c:116 and trace grabbag__file_copy_metadata(), focusing on the flac_stat() and flac_chmod() calls. Review the supplied PoC and strace evidence, then verify the metadata copy no longer permits a path replacement between checking and changing permissions. Done when the TOCTOU permission-change scenario is prevented and the relevant behavior remains correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100