Thinking about how one should avoid euidaccess, I noticed that this corner of remove.c wasn't quite right: if we call faccessat and it fails, there's no point in trying with crufty, less-robust interfaces.
While technically this is a correctness issue, the cases in which it makes a difference are so far-fetched that it's not worth trying to write the test case. Here's the fix: >From 0d48e1d317844ffcadb434a694438e14993a4be9 Mon Sep 17 00:00:00 2001 From: Jim Meyering <[email protected]> Date: Sat, 6 Mar 2010 13:16:19 +0100 Subject: [PATCH] remove: without -f, avoid unnecessary-expense/issues with euidaccess * src/remove.c (write_protected_non_symlink): If faccessat fails, return 1 or -1 directly, rather than falling back on euidaccess*. --- src/remove.c | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/remove.c b/src/remove.c index b6cfc8e..d0b2dae 100644 --- a/src/remove.c +++ b/src/remove.c @@ -171,9 +171,13 @@ write_protected_non_symlink (int fd_cwd, { /* This implements #1: on decent systems, either faccessat is native or /proc/self/fd allows us to skip a chdir. */ - if (!openat_needs_fchdir () - && faccessat (fd_cwd, file, W_OK, AT_EACCESS) == 0) - return 0; + if (!openat_needs_fchdir ()) + { + if (faccessat (fd_cwd, file, W_OK, AT_EACCESS) == 0) + return 0; + + return errno == EACCES ? 1 : -1; + } /* This implements #5: */ size_t file_name_len = strlen (full_name); -- 1.7.0.1.324.g3bb92
