current_check_refer_path(9)
π
current_check_refer_path β the Kernel API Manual girlie returns
okay so bestie, welcome to current_check_refer_path(9) β¨ this is the little kernel function that's basically the bouncer at the club door for renames and links, and honestly? she's doing the most so that Landlock stays watertight π«Ά
β¨ NAME β¨
current_check_refer_path β check if a rename or link action is allowed π«
like, literally: is this move/link legal or not, no cap.
π¦ SYNOPSIS π¦
int current_check_refer_path (struct dentry *const old_dentry , const
struct path *const new_dir , struct dentry *const new_dentry , const
bool removable , const bool exchange , const bool whiteout );
that's the whole signature, character for character, don't come for me π
π ARGUMENTS π
old_dentryβ the file or directory that someone's asking to move or link. the main character of this operation ngl π§new_dirβ the destination's parent directory. the new neighborhood fr.new_dentryβ the destination file or directory itself.removableβ set totrueif it's a rename operation β¨exchangeβ set totrueif it's a rename operation withRENAME_EXCHANGE.whiteoutβ set totrueif it's a rename operation withRENAME_WHITEOUT.
π DESCRIPTION π
okay so here's the lore. because of its unprivileged constraints, Landlock relies on file hierarchies (and not only inodes) to tie access rights to files π that's the whole design. and being able to link or rename a file hierarchy brings some challenges, because moving or linking a file β i.e. creating a new reference to an inode β can have an impact on the actions allowed for a set of files if it would change its parent directory (i.e. reparenting). it's giving "you can't sit with us" but for dentries π
so. to avoid trivial access right bypasses, Landlock first checks if the file or directory requested to be moved would gain new access rights inherited from its new hierarchy. then, before returning any error, Landlock checks that the parent source hierarchy and the destination hierarchy would allow the link or rename action. if it's not the case, an error with EACCES is returned to inform user space that there is no way to remove or create the requested source file type π if it should be allowed but the new inherited access rights would be greater than the source access rights, then the kernel returns an error with EXDEV π
prioritizing EACCES over EXDEV enables user space to abort the whole operation if there is no way to do it, or to manually copy the source to the destination if this remains allowed, e.g. because file creation is allowed on the destination directory but not direct linking β¨ like, iconic prioritization honestly.
bestie, remember:EACCESbeatsEXDEVhere, and that ordering is load-bearing. it's what lets user space know whether to give up entirely or fall back to a manual copy π«Ά
to achieve this goal, the kernel needs to compare two file hierarchies: the one identifying the source file or directory (including itself), and the destination one π this can be seen as a multilayer partial ordering problem. the kernel walks through these paths and collects in a matrix the access rights that are denied per layer. these matrices are then compared to see if the destination one has more (or the same) restrictions as the source one. if this is the case, the requested action will not return EXDEV β which doesn't mean the action is allowed π don't get it twisted.
the parent hierarchy of the source (i.e. parent directory), and the destination hierarchy must also be checked to verify that they explicitly allow such action (i.e. referencing, creation and potentially removal rights) π
so the kernel implementation is then required to rely on potentially four matrices of access rights:
- one for the source file or directory (i.e. the child)
- a potentially other one for the other source/destination (in case of
RENAME_EXCHANGE) - one for the source parent hierarchy
- and a last one for the destination hierarchy
these ephemeral matrices take some space on the stack, which limits the number of layers to a deemed reasonable number: 16 π that's the number, don't @ me.
π₯ RETURN π₯
0if access is allowed β-EXDEVifold_dentrywould inherit new access rights fromnew_dir-EACCESif file removal or creation is denied
πΈ SEE ALSO πΈ
Kernel file ./security/landlock/fs.c π« and her friends:
is_masked_device_ioctl(9)get_inode_id(9)is_access_to_paths_allowed(9)collect_domain_accesses(9)unmask_scoped_access(9)get_required_file_open_access(9)
go read them, iykyk π¦
and that's the page bestie π₯° brought to you by ./security/landlock, dated October 2026 β periodt, no cap, go protect those hierarchies π
β¨
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms