mirror of
https://github.com/apache/nuttx.git
synced 2026-09-23 07:14:28 +08:00
Documentation: describe FS permission interface and mount-crossing
Document inode_checkperm / inode_checkpathperm, mountpoint traverse vs open semantics, and the optional mountpt_operations.permission hook in file_permission.rst. Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
This commit is contained in:
committed by
Alan C. Assis
parent
08afc5f2cf
commit
4002e6af5f
@@ -57,3 +57,6 @@ target directory.
|
||||
Files created before permission support was enabled, or without stored
|
||||
attributes, default to mode ``0777`` until ``chmod``/``chown`` sets explicit
|
||||
metadata.
|
||||
|
||||
Path components above the littlefs mountpoint are enforced by the VFS; see
|
||||
:ref:`file-permission`.
|
||||
|
||||
@@ -211,3 +211,7 @@ will also fail. You cannot do this, for example:
|
||||
|
||||
See also NxFileSystem in
|
||||
`Porting Guide <https://cwiki.apache.org/confluence/display/NUTTX/Porting+Guide>`_
|
||||
|
||||
When ``CONFIG_FS_PERMISSION`` is enabled, pseudoFS directory modes also gate
|
||||
access into mounted volumes beneath them. See
|
||||
:ref:`file-permission`.
|
||||
|
||||
@@ -11,3 +11,13 @@ At runtime, simply use ``mount -t tmpfs /tmp`` to have a ``/tmp`` folder backed
|
||||
Be aware that TMPFS is backed by kernel memory thus don't expect to store big files on it and its size is limited by free kernel memory.
|
||||
|
||||
We can watch the size of TMPFS with ``df -h`` command, especially you can see the ``Size`` column of TMPFS changes when files are added or removed in the TMPFS folder. Changes in TMPFS size is always reflected by reverse changes of free kernel memory size.
|
||||
|
||||
Permissions
|
||||
===========
|
||||
|
||||
When ``CONFIG_FS_PERMISSION`` is enabled, tmpfs stores per-object owner, group,
|
||||
and mode and enforces them on path operations inside the volume. It also
|
||||
implements the optional ``mountpt_operations.permission`` hook.
|
||||
|
||||
Access into the mount from the pseudoFS is gated by the VFS (parent and
|
||||
mountpoint ``X_OK``). See :ref:`file-permission`.
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
.. _file-permission:
|
||||
|
||||
========================================
|
||||
Filesystem Permission Interface
|
||||
========================================
|
||||
|
||||
When ``CONFIG_FS_PERMISSION`` is enabled, the VFS applies POSIX-style
|
||||
discretionary access control (DAC) using the caller's effective credentials
|
||||
(``tg_euid`` / ``tg_egid``). This page describes the common inode helpers,
|
||||
how mountpoints participate, and how access across a mount is gated by
|
||||
pseudoFS directory modes.
|
||||
|
||||
Prerequisite reading: :ref:`user-identity`.
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
=============================== =============================================
|
||||
Option Role
|
||||
=============================== =============================================
|
||||
``CONFIG_SCHED_USER_IDENTITY`` Per-task-group UID/GID credentials
|
||||
``CONFIG_PSEUDOFS_ATTRIBUTES`` Store ``i_mode`` / ``i_owner`` / ``i_group``
|
||||
on pseudoFS inodes
|
||||
``CONFIG_FS_PERMISSION`` Enable DAC helpers and VFS enforcement
|
||||
(depends on the two options above)
|
||||
=============================== =============================================
|
||||
|
||||
Without ``CONFIG_FS_PERMISSION``, the helpers described here return success
|
||||
and no mode-based checks are performed.
|
||||
|
||||
Helpers
|
||||
=======
|
||||
|
||||
``inode_checkperm``
|
||||
Check ``amode`` (``R_OK`` / ``W_OK`` / ``X_OK``) against an inode's
|
||||
``i_owner`` / ``i_group`` / ``i_mode``. Empty macro returning ``0``
|
||||
when ``CONFIG_FS_PERMISSION`` is disabled.
|
||||
|
||||
``inode_checkpathperm``
|
||||
Require ``X_OK`` on every ancestor of an inode, and on the inode itself
|
||||
when it is a pseudo directory or a mountpoint (directory search /
|
||||
traverse). If ``amode`` is non-zero, also require that access on the
|
||||
inode. Takes the inode tree read lock unless ``INODE_CHECK_LOCKED`` is
|
||||
set (caller already holds ``inode_lock`` / ``inode_rlock``). Empty
|
||||
macro returning ``0`` when ``CONFIG_FS_PERMISSION`` is disabled.
|
||||
|
||||
``inode_checkopenperm``
|
||||
Validate that the inode supports the requested open access, then apply
|
||||
mode checks for non-mountpoint inodes.
|
||||
|
||||
``fs_checkmode``
|
||||
Core owner/group/other test used by the helpers above and by filesystems
|
||||
such as tmpfs and littlefs.
|
||||
|
||||
Optional mountpoint hook
|
||||
------------------------
|
||||
|
||||
``struct mountpt_operations`` may provide a ``permission`` method for
|
||||
in-volume DAC. The field is at the **end** of the structure so existing
|
||||
positional initialisers remain valid.
|
||||
|
||||
* **tmpfs** implements ``tmpfs_permission``.
|
||||
* Filesystems without Unix ownership on disk (for example FAT and ROMFS)
|
||||
leave the method ``NULL``.
|
||||
|
||||
The VFS mount-crossing gate does **not** depend on this hook. Entry into a
|
||||
volume is enforced with ``inode_checkpathperm`` against the mountpoint
|
||||
inode's stored ``i_mode``. In-volume checks remain the filesystem's job
|
||||
(tmpfs and littlefs enforce DAC inside their own open/mkdir/path helpers.
|
||||
``mops->permission`` is an optional common entry point for the same policy;
|
||||
the VFS does not invoke it for mount-crossing).
|
||||
|
||||
Open vs traverse
|
||||
================
|
||||
|
||||
Mountpoint inodes are **not** open-mode-checked by ``inode_checkopenperm``.
|
||||
Applying the mount directory's mode bits as file open modes would require
|
||||
read/write on the mount directory merely to open a file beneath it.
|
||||
|
||||
Traverse is separate: callers use ``inode_checkpathperm`` so parent
|
||||
directories and the mountpoint itself still require ``X_OK``.
|
||||
|
||||
Typical order after a successful ``inode_find``:
|
||||
|
||||
1. ``inode_checkpathperm(inode, 0, 0)`` — search permission on the path
|
||||
prefix (and on the mountpoint when entering a volume). Call sites that
|
||||
already hold the tree lock pass ``INODE_CHECK_LOCKED``; mount and
|
||||
pseudoFS create/remove may pass a non-zero ``amode`` (for example
|
||||
``W_OK``) to combine traverse and target checks in one call.
|
||||
2. Operation-specific checks — ``inode_checkopenperm``, or the
|
||||
filesystem's own methods for paths inside a mount.
|
||||
|
||||
Mount-crossing
|
||||
==============
|
||||
|
||||
Path walk stops at a mountpoint and returns that inode plus a relative path
|
||||
into the volume. Without traverse checks, a restrictive mode on a pseudoFS
|
||||
parent would not protect objects under a filesystem mounted beneath it.
|
||||
|
||||
Example::
|
||||
|
||||
/secure_dir # pseudoFS directory, mode 0700, owner root
|
||||
/secure_dir/mnt # mounted volume (tmpfs, FAT, ...)
|
||||
/secure_dir/mnt/a # object inside the volume
|
||||
|
||||
``inode_checkpathperm`` requires ``X_OK`` on ``secure_dir`` and on the
|
||||
mountpoint ``mnt``. A non-root open of ``/secure_dir/mnt/a`` therefore
|
||||
returns ``EACCES``, even if the mounted filesystem itself has no Unix DAC.
|
||||
|
||||
Where the checks run
|
||||
--------------------
|
||||
|
||||
* After ``inode_find`` in open, unlink, mkdir, rmdir, rename, stat, chstat,
|
||||
statfs, readlink, mount, and umount. ``inode_checkpathperm`` takes
|
||||
``inode_rlock`` unless the caller already holds the tree lock
|
||||
(``INODE_CHECK_LOCKED``).
|
||||
* Inside ``inode_reserve`` / ``inode_remove`` for pseudoFS create and remove
|
||||
(ancestor ``X_OK`` and parent ``W_OK`` in one call, under ``inode_lock``).
|
||||
|
||||
Who enforces what
|
||||
-----------------
|
||||
|
||||
* **PseudoFS parent dirs** — ``X_OK`` (and ``W_OK`` when creating/removing)
|
||||
* **Mountpoint inode** — ``X_OK`` to enter the volume (stored ``i_mode``)
|
||||
* **Inside the volume** — Filesystem methods; optional ``mops->permission``
|
||||
* **FAT / ROMFS** — No Unix ownership on disk; entry still gated by the
|
||||
mountpoint ``i_mode``
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
* ``fs/inode/fs_inode.c`` — ``inode_checkperm``, ``inode_checkpathperm``
|
||||
* ``include/nuttx/fs/fs.h`` — ``struct mountpt_operations``
|
||||
* ``fs/tmpfs/fs_tmpfs.c`` — ``tmpfs_permission``
|
||||
* :ref:`user-identity` — credential model
|
||||
* :doc:`/components/filesystem/littlefs` — littlefs in-volume DAC
|
||||
* :doc:`/components/filesystem/tmpfs` — tmpfs overview
|
||||
@@ -16,6 +16,7 @@ Implementation Details
|
||||
device_nodes.rst
|
||||
drivers_design.rst
|
||||
file_descriptors.rst
|
||||
file_permission.rst
|
||||
hardfaults.rst
|
||||
interrupt_controls.rst
|
||||
ioctl.rst
|
||||
|
||||
@@ -86,7 +86,9 @@ Configuration
|
||||
|
||||
``CONFIG_FS_PERMISSION``
|
||||
Enables filesystem ownership and permission enforcement. Requires
|
||||
``CONFIG_SCHED_USER_IDENTITY``.
|
||||
``CONFIG_SCHED_USER_IDENTITY`` and ``CONFIG_PSEUDOFS_ATTRIBUTES``.
|
||||
See :ref:`file-permission` for the VFS helpers, mount-crossing
|
||||
traverse rules, and testing notes.
|
||||
|
||||
Pseudo-Filesystem Ownership
|
||||
===========================
|
||||
@@ -96,5 +98,10 @@ enabled, ``inode_alloc()`` assigns ``i_owner`` and ``i_group`` from the
|
||||
caller's effective credentials. This covers
|
||||
message queues (``mq_open()``), named semaphores (``sem_open()``), shared
|
||||
memory objects (``shm_open()``), FIFOs (``mkfifo()``), and pseudo-files
|
||||
created through the same inode reservation path. Open-time permission checks
|
||||
use ``inode_checkopenperm()`` (or ``inode_checkperm()`` for message queues).
|
||||
created through the same inode reservation path.
|
||||
|
||||
Path resolution requires directory search permission (``X_OK``) on ancestors
|
||||
via ``inode_checkpathperm()``. Open-time checks on the final node use
|
||||
``inode_checkopenperm()`` (or ``inode_checkperm()`` for named IPC
|
||||
objects). Full details, including mounts under private pseudoFS parents,
|
||||
are in :ref:`file-permission`.
|
||||
|
||||
Reference in New Issue
Block a user