casaroli opened a new pull request, #20835:
URL: https://github.com/apache/nuttx/pull/20835

   ## Summary
   
   This PR fixes three problems of V9FS with the owner, the mode and the times 
of files.
   
   **`Tsetattr` times.** In 9P2000.L, `P9_SETATTR_ATIME` and `P9_SETATTR_MTIME` 
tell the server to change the time, and `P9_SETATTR_ATIME_SET` and 
`P9_SETATTR_MTIME_SET` tell it to use the time in the request. V9FS sent only 
the `*_SET` bits. So `utimens()`, `futimens()` and `utimensat()` returned 0, 
but the server did not change the times. V9FS now sends both bits.
   
   **`Tsetattr` mode.** V9FS sent only the permission bits (`st_mode & 07777`). 
QEMU with `security_model=mapped-xattr` stores the mode as it is in the 
`user.virtfs.mode` xattr and returns it in `Rgetattr`. So after `chmod()`, 
`stat()` showed no file type (a regular file had mode `0644` instead of 
`0100644`). V9FS now gets the current mode with `Tgetattr` and sends its file 
type bits with the new permission bits, as the Linux client does.
   
   **Owner of new files.** V9FS attached to the server only once, at mount 
time. A 9P2000.L server gives a new file the user of the fid that creates it 
(the `n_uname` of `Tattach`). So every file, directory and symbolic link that 
NuttX created on a V9FS mount belonged to the user that did the mount, usually 
uid 0. `Tlcreate`, `Tmkdir` and `Tsymlink` also sent the real group ID, not the 
effective group ID. With `CONFIG_SCHED_USER_IDENTITY`, V9FS now attaches once 
for each effective user ID that uses the mount, and starts each walk from the 
root fid of the caller. The create requests send the effective group ID. V9FS 
clunks the extra root fids at unmount. Without `CONFIG_SCHED_USER_IDENTITY` 
nothing changes: all IDs are 0. `chown()` and `fchown()` already send 
`Tsetattr`, and `stat()` already shows the IDs that the server returns.
   
   The last commit documents the owner and the group in 
`Documentation/os/filesystem/v9fs.rst`, with the QEMU `security_model` option, 
and adds a note to the qemu-armv8a 9p example. To keep the owner, the group and 
the mode, run QEMU with:
   
   ```
   -fsdev local,security_model=mapped-xattr,id=fsdev0,path=<share-path> \
   -device virtio-9p-device,id=fs0,fsdev=fsdev0,mount_tag=<mount_tag>
   ```
   
   QEMU then keeps them in the host xattrs `user.virtfs.uid`, `user.virtfs.gid` 
and `user.virtfs.mode`.
   
   ## Impact
   
   - Only V9FS.
   - `utimens()`, `futimens()`, `utimensat()` and `utimes()` now change the 
times on the server.
   - `chmod()` and `fchmod()` send one more request (`Tgetattr`). With 
`security_model=none` and `passthrough`, QEMU calls `chmod()` on the host, 
which ignores the file type bits, so there is no change.
   - The new owner code is under `CONFIG_SCHED_USER_IDENTITY`. The server holds 
one more root fid for each user that uses the mount. `fs/v9fs/client.o` text on 
qemu-armv8a:nsh with V9FS, owner commit only: 8727 -> 8775 bytes without 
`CONFIG_SCHED_USER_IDENTITY`, 8727 -> 9259 bytes with it.
   
   ## Testing
   
   qemu-armv8a:knsh under HVF on a macOS host, QEMU 11.0.0, a share with 
`security_model=mapped-xattr`.
   
   Times and mode: a test program sets the times of a file to 1000000000 with 
`utimensat()`, calls `chmod(0640)`, and reads them back with `stat()`.
   
   | Check | master | this PR |
   |---|---|---|
   | mtime after `utimensat()` to 1000000000 | current time | 1000000000 |
   | mode after `chmod(0640)` | `0640` | `0100640` |
   
   Owner, with `CONFIG_SCHED_USER_IDENTITY`, `CONFIG_FS_LINKS` and 
`CONFIG_FS_PERMISSION`; the test program runs as uid 0:
   
   | Check | master | this PR |
   |---|---|---|
   | uid 0 creates a file: `stat()` | 0:0 | 0:0 |
   | `chown(1000, 1000)`, `chown(-1, 1001)`, `fchown(1002, 1002)`: `stat()` | 
PASS | PASS |
   | `seteuid(1000)`, `setegid(1000)`, then `open(O_CREAT)` | 0:0 | 1000:1000 |
   | same, `mkdir()` | 0:0 | 1000:1000 |
   | same, `symlink()`, then `lstat()` | 0:0 | 1000:1000 |
   | child with `setgid(2000)`, `setuid(2000)` creates a file | 0:2000 | 
2000:2000 |
   | uid 0 creates a file in the directory of uid 1000 | 0:0 | 0:0 |
   | host xattr `user.virtfs.uid` of the file of uid 1000 | 0 | 1000 |
   
   The owner test on a `security_model=none` share gives the same results on 
master and with this PR: `stat()` shows the owner of the host file, and 
`chown()` fails with `EPERM`. On a `security_model=passthrough` share with QEMU 
not root, the creation of a file fails with `EPERM` on master and with this PR.
   
   ostest passes on qemu-armv8a:knsh and qemu-armv8a:nsh. The V9FS `link()` and 
`fsync()` tests pass. qemu-armv8a:nsh builds with V9FS without 
`CONFIG_SCHED_USER_IDENTITY`. `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]

Reply via email to