mirror of
https://github.com/apache/nuttx.git
synced 2026-08-25 15:37:23 +00:00
Some checks are pending
Build Documentation / build-html (push) Waiting to run
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
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>
137 lines
5.6 KiB
ReStructuredText
137 lines
5.6 KiB
ReStructuredText
.. _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
|