casaroli opened a new pull request, #21453:
URL: https://github.com/apache/nuttx/pull/21453
## Summary
With `CONFIG_FS_PERMISSION`, a pseudo directory with no x bit cannot be
found again, also by root: `chmod("/d", 0644)` works, then `stat("/d")`,
`opendir("/d")` and `chmod("/d", 0755)` fail with EACCES.
`inode_checkpathperm()` checks X_OK on the inode itself when it is a pseudo
directory or a mount point. POSIX needs search permission only on the
directories of the path prefix.
The helper now checks X_OK on the ancestors only, and each caller says what
it needs on the inode. A path from `inode_find()` needs X_OK on a mount point
only when it goes into the volume. `inode_reserve()` and `inode_remove()` pass
W_OK and X_OK on the parent. `mount()` and `umount()` keep W_OK and X_OK on the
target.
`chdir()` needs search permission on the last component too, and it only
called `stat()`. It now tests the x bit of the directory for the effective IDs.
Root needs any x bit, the same rule as `access()` and `exec()`. This also fixes
`chdir()` into a directory of a mounted file system with no x bit, which worked
before.
## Impact
Only builds with `CONFIG_FS_PERMISSION` change. No defconfig sets it.
Without it, `inode_checkpathperm()` is still a macro that gives 0, and the
`chdir()` test is not compiled.
Behaviour with the option: a directory with no x bit is now visible to
`stat()`, `opendir()` (with the r bit) and `chmod()`. A prefix directory with
no x bit still fails with EACCES for every user. A path into a volume through a
mount point with no x bit still fails with EACCES. uid 0 gets no new privilege
in the VFS: `fs_checkmode()` does not change.
Limit: `stat()` reports the mode of the root of the volume, not the mode of
the mount point inode, so `chdir()` to a mount point with no x bit now returns
0. It gives no access: each path through the working directory still fails with
EACCES (tested).
Limits from reading the code, not run: `chdir()` as root into a directory of
a volume with no x bit at all (0600) now gives EACCES (before: 0).
`stat("/d/.")` with `d` without x succeeds, because "/." is removed before the
check; POSIX wants EACCES.
Documentation: `Documentation/os/filesystem/file_permission.rst` is updated
in its own commit.
## Testing
The tests ran on base 39a1f27900c; the branch is rebased on 3d57048f1e1 (no
change in the touched files), apps f04aee601. Test program: 62 cases with root
and with uid 1000, on pseudo directories and on tmpfs mounts, with `FS_TMPFS
SCHED_USER_IDENTITY PSEUDOFS_ATTRIBUTES FS_PERMISSION`. Two of the cases run
only when `chdir()` to the mount point returns 0, so master runs 60.
| Config | Mode | master | this PR | ostest master / this PR |
|---|---|---|---|---|
| qemu-armv8a:knsh (HVF) | kernel | 45 of 60 PASS | 62 of 62 PASS | 0 / 0 |
| qemu-armv8a:nsh (HVF) | flat | 45 of 60 PASS | 62 of 62 PASS | 0 / 0 |
| mps2-an500:knsh (TCG) | protected | 45 of 60 PASS | 62 of 62 PASS | not
run |
Build only, with `EXTRAFLAGS="-Wno-cpp -Werror"`, no compiler warnings:
qemu-armv8a:nsh, qemu-armv8a:knsh, mps2-an500:knsh, rv-virt:citest,
rv-virt:knsh64, sim:nsh; qemu-armv8a:nsh and rv-virt:citest also with
`FS_PERMISSION`. The change has no arch code.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]