Lines Matching +full:mount +full:- +full:matrix

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Landlock LSM - Filesystem management and hooks
5 * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net>
6 * Copyright © 2018-2020 ANSSI
7 * Copyright © 2021-2022 Microsoft Corporation
22 #include <linux/mount.h>
44 __releases(object->lock) in release_inode()
46 struct inode *const inode = object->underobj; in release_inode()
50 spin_unlock(&object->lock); in release_inode()
58 object->underobj = NULL; in release_inode()
63 sb = inode->i_sb; in release_inode()
64 atomic_long_inc(&landlock_superblock(sb)->inode_refs); in release_inode()
65 spin_unlock(&object->lock); in release_inode()
67 * Because object->underobj was not NULL, hook_sb_delete() and in release_inode()
69 * landlock_inode(inode)->object while it is not NULL. It is therefore in release_inode()
70 * not necessary to lock inode->i_lock. in release_inode()
72 rcu_assign_pointer(landlock_inode(inode)->object, NULL); in release_inode()
78 if (atomic_long_dec_and_test(&landlock_superblock(sb)->inode_refs)) in release_inode()
79 wake_up_var(&landlock_superblock(sb)->inode_refs); in release_inode()
95 object = rcu_dereference(inode_sec->object); in get_inode_object()
97 if (likely(refcount_inc_not_zero(&object->usage))) { in get_inode_object()
105 spin_lock(&object->lock); in get_inode_object()
106 spin_unlock(&object->lock); in get_inode_object()
123 spin_lock(&inode->i_lock); in get_inode_object()
124 if (unlikely(rcu_access_pointer(inode_sec->object))) { in get_inode_object()
126 spin_unlock(&inode->i_lock); in get_inode_object()
139 rcu_assign_pointer(inode_sec->object, new_object); in get_inode_object()
140 spin_unlock(&inode->i_lock); in get_inode_object()
145 /* clang-format off */
151 /* clang-format on */
155 * by a ruleset/layer. This must be ORed with all ruleset->fs_access_masks[]
158 /* clang-format off */
161 /* clang-format on */
174 if (!d_is_dir(path->dentry) && in landlock_append_fs_rule()
176 return -EINVAL; in landlock_append_fs_rule()
177 if (WARN_ON_ONCE(ruleset->num_layers != 1)) in landlock_append_fs_rule()
178 return -EINVAL; in landlock_append_fs_rule()
183 ~(ruleset->fs_access_masks[0] | ACCESS_INITIALLY_DENIED); in landlock_append_fs_rule()
184 object = get_inode_object(d_backing_inode(path->dentry)); in landlock_append_fs_rule()
187 mutex_lock(&ruleset->lock); in landlock_append_fs_rule()
189 mutex_unlock(&ruleset->lock); in landlock_append_fs_rule()
198 /* Access-control management */
219 domain, rcu_dereference(landlock_inode(inode)->object)); in find_rule()
253 for (layer_level = 0; layer_level < rule->num_layers; layer_level++) { in unmask_layers()
255 &rule->layers[layer_level]; in unmask_layers()
256 const layer_mask_t layer_bit = BIT_ULL(layer->level - 1); in unmask_layers()
268 if (layer->access & BIT_ULL(access_bit)) in unmask_layers()
281 * /proc/<pid>/fd/<file-descriptor>
285 return (dentry->d_sb->s_flags & SB_NOUSER) || in is_nouser_or_private()
296 for (layer_level = 0; layer_level < domain->num_layers; layer_level++) in get_handled_accesses()
297 access_dom |= domain->fs_access_masks[layer_level]; in get_handled_accesses()
302 * init_layer_masks - Initialize layer masks from an access request
328 for (layer_level = 0; layer_level < domain->num_layers; layer_level++) { in init_layer_masks()
339 (domain->fs_access_masks[layer_level] | in init_layer_masks()
432 /* LANDLOCK_ACCESS_FS_REFER alone must return -EXDEV. */ in is_eacces()
447 * is_access_to_paths_allowed - Check accesses for requests with a common path
456 * @layer_masks_parent1: Pointer to a matrix of layer masks per access
458 * this matrix can be unset according to the @path walk. An empty matrix
460 * those identified by @access_request_parent1). This matrix can
464 * pointer must be NULL for non-refer actions (i.e. not link nor rename).
482 * - true if the access request is granted;
483 * - false otherwise.
508 if (is_nouser_or_private(path->dentry)) in is_access_to_paths_allowed()
510 if (WARN_ON_ONCE(domain->num_layers < 1 || !layer_masks_parent1)) in is_access_to_paths_allowed()
607 if (walker_path.dentry == walker_path.mnt->mnt_root) { in is_access_to_paths_allowed()
609 /* Ignores hidden mount points. */ in is_access_to_paths_allowed()
626 !!(walker_path.mnt->mnt_flags & MNT_INTERNAL); in is_access_to_paths_allowed()
648 return -EACCES; in check_access_path()
696 * collect_domain_accesses - Walk through a file path and collect accesses
704 * @mnt_root directory used as a mount point. This mount point is the common
710 * only handles walking on the same mount point and only checks one set of
714 * - true if all the domain access rights are allowed for @dir;
715 * - false if the walk reached @mnt_root.
761 * current_check_refer_path - Check if a rename or link action is allowed
793 * The kernel walks through these paths and collects in a matrix the access
809 * - 0 if access is allowed;
810 * - -EXDEV if @old_dentry would inherit new access rights from @new_dir;
811 * - -EACCES if file removal or creation is denied.
828 if (WARN_ON_ONCE(dom->num_layers < 1)) in current_check_refer_path()
829 return -EACCES; in current_check_refer_path()
831 return -ENOENT; in current_check_refer_path()
834 return -ENOENT; in current_check_refer_path()
836 get_mode_access(d_backing_inode(new_dentry)->i_mode); in current_check_refer_path()
841 get_mode_access(d_backing_inode(old_dentry)->i_mode); in current_check_refer_path()
847 /* The mount points are the same for old and new paths, cf. EXDEV. */ in current_check_refer_path()
848 if (old_dentry->d_parent == new_dir->dentry) { in current_check_refer_path()
851 * for same-directory referer (i.e. no reparenting). in current_check_refer_path()
860 return -EACCES; in current_check_refer_path()
866 /* Saves the common mount point. */ in current_check_refer_path()
867 mnt_dir.mnt = new_dir->mnt; in current_check_refer_path()
868 mnt_dir.dentry = new_dir->mnt->mnt_root; in current_check_refer_path()
870 /* new_dir->dentry is equal to new_dentry->d_parent */ in current_check_refer_path()
872 old_dentry->d_parent, in current_check_refer_path()
875 dom, mnt_dir.dentry, new_dir->dentry, &layer_masks_parent2); in current_check_refer_path()
898 return -EACCES; in current_check_refer_path()
906 return -EXDEV; in current_check_refer_path()
917 WARN_ON_ONCE(landlock_inode(inode)->object); in hook_inode_free_security()
920 /* Super-block hooks */
934 spin_lock(&sb->s_inode_list_lock); in hook_sb_delete()
935 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { in hook_sb_delete()
939 if (!atomic_read(&inode->i_count)) in hook_sb_delete()
946 spin_lock(&inode->i_lock); in hook_sb_delete()
950 * could lead to a NULL dereference of inode->security or a in hook_sb_delete()
954 if (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW)) { in hook_sb_delete()
955 spin_unlock(&inode->i_lock); in hook_sb_delete()
960 object = rcu_dereference(landlock_inode(inode)->object); in hook_sb_delete()
963 spin_unlock(&inode->i_lock); in hook_sb_delete()
968 spin_unlock(&inode->i_lock); in hook_sb_delete()
975 spin_lock(&object->lock); in hook_sb_delete()
976 if (object->underobj == inode) { in hook_sb_delete()
977 object->underobj = NULL; in hook_sb_delete()
978 spin_unlock(&object->lock); in hook_sb_delete()
982 * Because object->underobj was not NULL, in hook_sb_delete()
985 * landlock_inode(inode)->object while it is not NULL. in hook_sb_delete()
986 * It is therefore not necessary to lock inode->i_lock. in hook_sb_delete()
988 rcu_assign_pointer(landlock_inode(inode)->object, NULL); in hook_sb_delete()
999 spin_unlock(&object->lock); in hook_sb_delete()
1010 spin_unlock(&sb->s_inode_list_lock); in hook_sb_delete()
1017 spin_lock(&sb->s_inode_list_lock); in hook_sb_delete()
1021 spin_unlock(&sb->s_inode_list_lock); in hook_sb_delete()
1027 wait_var_event(&landlock_superblock(sb)->inode_refs, in hook_sb_delete()
1028 !atomic_long_read(&landlock_superblock(sb)->inode_refs)); in hook_sb_delete()
1033 * topology (i.e. the mount namespace), changing it may grant access to files
1037 * processes. Non-landlocked processes may still change the namespace of a
1038 * landlocked process, but this kind of threat must be handled by a system-wide
1039 * access-control security policy.
1041 * This could be lifted in the future if Landlock can safely handle mount
1043 * update the current domain (which is currently read-only) by taking into
1044 * account the accesses of the source and the destination of a new mount point.
1055 return -EPERM; in hook_sb_mount()
1063 return -EPERM; in hook_move_mount()
1067 * Removing a mount point may reveal a previously hidden file hierarchy, which
1074 return -EPERM; in hook_sb_umount()
1081 return -EPERM; in hook_sb_remount()
1085 * pivot_root(2), like mount(2), changes the current mount namespace. It must
1097 return -EPERM; in hook_sb_pivotroot()
1116 /* old_dir refers to old_dentry->d_parent and new_dir->mnt */ in hook_path_rename()
1166 * get_required_file_open_access - Get access needed to open a file
1178 if (file->f_mode & FMODE_READ) { in get_required_file_open_access()
1180 if (S_ISDIR(file_inode(file)->i_mode)) in get_required_file_open_access()
1184 if (file->f_mode & FMODE_WRITE) in get_required_file_open_access()
1187 if (file->f_flags & __FMODE_EXEC) in get_required_file_open_access()
1202 landlock_file(file)->allowed_access = LANDLOCK_MASK_ACCESS_FS; in hook_file_alloc_security()
1231 dom, &file->f_path, in hook_file_open()
1258 landlock_file(file)->allowed_access = allowed_access; in hook_file_open()
1263 return -EACCES; in hook_file_open()
1278 if (landlock_file(file)->allowed_access & LANDLOCK_ACCESS_FS_TRUNCATE) in hook_file_truncate()
1280 return -EACCES; in hook_file_truncate()