casaroli opened a new pull request, #20836: URL: https://github.com/apache/nuttx/pull/20836
## Summary On a mount point, `lchown()`, `lchmod()` and `lutimens()` changed the file that a symbolic link points to, not the link. The same is true for `fchownat()`, `fchmodat()` and `utimensat()` with `AT_SYMLINK_NOFOLLOW`. `chstat_recursive()` gives the `chstat()` method of the file system the same flags for `chown()` and for `lchown()`, so the file system cannot know that it must not follow the link. The pseudo file system was correct, because `inode_chstat()` gets the `resolve` argument. This PR adds the flag `CH_STAT_NOFOLLOW` to `include/nuttx/fs/fs.h`. `chstat_recursive()` sets it when the caller does not resolve the link. The file systems that have symbolic links use it: - V9FS walks to the link without following it, as its `lstat()` does. - rpmsgfs: the server calls `lchmod()`, `lchown()` and `lutimens()`. - hostfs on the simulator: `host_chstat()` calls `fchmodat()`, `fchownat()` and `utimensat()` with `AT_SYMLINK_NOFOLLOW`. On a Linux host, `lchmod()` of a link then fails with `EOPNOTSUPP`, as on Linux. The other file systems with a `chstat()` method (tmpfs, littlefs, NFS, userfs, unionfs) have no symbolic links in NuttX or pass the flags on, so they need no change. The last commit documents the flag in `Documentation/os/filesystem/index.rst`. ## Impact - `lchown()`, `lchmod()`, `lutimens()` and the `*at()` functions with `AT_SYMLINK_NOFOLLOW` on V9FS, rpmsgfs and simulator hostfs mounts. `chown()`, `chmod()` and `utimens()` do not change. - A file system that does not know the flag ignores it, so the behaviour of other file systems does not change. - An rpmsgfs server without this change ignores the flag and follows the link, as before. - With QEMU `security_model=mapped-xattr`, `lchmod()` on V9FS needs the V9FS `Tsetattr` mode fix of #20835. Without it, the server stores the mode with no file type, and the link becomes a regular file. `lutimens()` on V9FS needs the `Tsetattr` time fix of #20835; without it, V9FS does not change any times. ## Testing A test program makes a file and a symbolic link to it, calls `lchown(link, 1003, 1004)`, `lchmod(link, 0600)` and `utimensat(link, AT_SYMLINK_NOFOLLOW)`, and checks with `lstat()` and `stat()` that only the link changed. Then it calls `chown()`, `chmod()` and `utimensat(0)` on the link and checks that they change the target. Results on V9FS (qemu-armv8a:knsh under HVF on a macOS host, QEMU 11.0.0, a share with `security_model=mapped-xattr`, `CONFIG_FS_LINKS`) and on hostfs (sim:nsh on a Linux arm64 host, run as root): | Check | V9FS master | V9FS this PR + #20835 | hostfs master | hostfs this PR | |---|---|---|---|---| | `lchown(link)`: `lstat(link)` | 0:0 | 1003:1004 | 0:0 | 1003:1004 | | `lchown(link)`: `stat(target)` | 1003:1004 | 0:0 | 1003:1004 | 0:0 | | `lchmod(link, 0600)`: `lstat(link)` | 0120777 | 0120600 | 0120777 | `EOPNOTSUPP` | | `lchmod(link, 0600)`: `stat(target)` | 0600 | 0100644 | 0100600 | 0100644 | | `utimensat(link, NOFOLLOW)`: link mtime | not changed | 1200000000 | not changed | 1200000000 | | `utimensat(link, NOFOLLOW)`: target mtime | not changed (no V9FS time change on master) | not changed | 1200000000 | not changed | | `chown()`, `chmod()`, `utimensat(0)` on the link change the target | yes (times: no) | yes | yes | yes | With this PR alone on V9FS, `lchown()` and `lchmod()` change the link and not the target, but `lchmod()` removes the file type of the link (see Impact), and `lutimens()` changes no time. On the pseudo file system the results are the same before and after this PR (all checks pass). tmpfs has no symbolic links (`symlink()` gives `ENOSYS`). ostest passes on qemu-armv8a:knsh and qemu-armv8a:nsh (HVF, macOS host). qemu-armv8a:rpserver builds with no warnings. `tools/checkpatch.sh -c -u -m -g` passes. -- 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]
