On 03/11/2026 05:08, Collin Funk wrote:
It would also be good to add a test for other races, but I still need to think of the best way to do it. Perhaps for the rename one, a long file name could maybe reproduce it consistently, since it calls renameatu N times where N is the length of the file name.The chmod one can probably only be done with a breakpoint or something like that.
I was thinking about using strace to send a SIGSTOP for something similar recently, so it's probably worth adding such a test for reference at least. I've attached a test that fails without the fix and passes with it.
diff --git a/src/shred.c b/src/shred.c
+ ok = (do_wipefd (fd, qname, s, flags) + && (! flags->remove_file || wipename (dirfd, name, qname, flags)));- if (close (fd) != 0)+ done: + if (0 <= fd && close (fd) < 0) { error (0, errno, _("%s: failed to close"), qname); ok = false; } - if (ok && flags->remove_file) - ok = wipename (name, qname, flags); + if (dirfd != AT_FDCWD) + close (dirfd); return ok; }
That unlinks the file even if close() returned EIO. I think it would be better to reorder to keep the file around in that case, at least as a witness to the failing overwrite operation. cheers, Padraig
chmod-race.sh
Description: application/shellscript
