Skip to content

chmod: report the real error for files below the -R operand - #15935

Open
eylulseyit wants to merge 2 commits into
uutils:mainfrom
eylulseyit:chmod-recursive-eperm
Open

eylulseyit wants to merge 2 commits into
uutils:mainfrom
eylulseyit:chmod-recursive-eperm

Conversation

@eylulseyit

Copy link
Copy Markdown
Contributor

With -R, if chmod couldn't change the mode of a file below the operand, every error except EROFS was shown as "cannot access ... Permission denied". For a file the user doesn't own, that's wrong: the real error is EPERM, and GNU prints "changing permissions of 'X': Operation not permitted".

safe_chmod_file() now reports the error from chmod as is, like change_file() does for the operand. The test uses -R -L with a symlink to /etc/passwd to get EPERM below the operand without root.

Closes #15934

@eylulseyit

Copy link
Copy Markdown
Contributor Author

The failing checks look unrelated to this change. Code Coverage and GNU (SELinux) failed during setup, before any tests ran. MinRustV failed on test_nohup_replaced_stdin_is_not_readable, which happens on ubuntu-26.04 runners; I opened #15937 for the underlying cat bug. Could someone re-run the setup failures?

@sylvestre

Copy link
Copy Markdown
Contributor

thanks for looking into this!
This fixes the error message, but #15934 also reports the -v line below the operand (no old mode, printed before the error). Please fix that here too, or don't close the issue with this PR.

@sylvestre

Copy link
Copy Markdown
Contributor

a bunch of jobs are failing

Comment thread src/uu/chmod/src/chmod.rs Outdated
@@ -843,13 +843,7 @@ impl Chmoder {
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the issue also covers this -v line: no old mode / symbolic form, and printed before the error
could you please fix it too, or not close #15934 with this PR? thanks

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, I fixed the -v line in this PR, it now matches GNU.

Comment thread tests/by-util/test_chmod.rs Outdated
fn test_chmod_recursive_reports_real_error_below_operand() {
use rustix::process::geteuid;

// A file found while recursing that the user does not own must be

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please make this comment shorter? :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done :>

@fixfon

fixfon commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

The EPERM path now matches GNU 9.12, but the entry name is still lost when metadata_at fails with anything other than PermissionDenied (tested on Linux x86_64, head 4ba6487):

mkdir d; ln -s missing d/dang; chmod -R -L 755 d

GNU: chmod: cannot operate on dangling symlink 'd/dang'
PR (and main): chmod: No such file or directory

In safe_traverse_dir, the dir_fd.metadata_at(&entry_name, follow) error only gets entry_path attached in the PermissionDenied arm; the err.into() fallback drops it. Wrapping that arm with the path too would cover ENOENT.

Smaller gap in the same area: with -v, a failed change prints failed to change mode of 'd/p' to 755, while GNU prints from 0644 (rw-r--r--) to 0755 (rwxr-xr-x).

When chmod could not change the mode of a file found while recursing, every error except EROFS was reported as "cannot access ... Permission denied", even EPERM for a file the user doesn't own. Now the error from chmod is shown as is, the same way change_file() already does for the operand.
Show the old and new mode, drop the extra 'file' word for the operand, and print the line after the error, as GNU does.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chmod -R: "cannot access … Permission denied" for files below the operand that the user doesn't own

3 participants