1cb2c7d1aSMickaël Salaün /* SPDX-License-Identifier: GPL-2.0-only */ 2cb2c7d1aSMickaël Salaün /* 3cb2c7d1aSMickaël Salaün * Landlock LSM - Filesystem management and hooks 4cb2c7d1aSMickaël Salaün * 5cb2c7d1aSMickaël Salaün * Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net> 6cb2c7d1aSMickaël Salaün * Copyright © 2018-2020 ANSSI 7cb2c7d1aSMickaël Salaün */ 8cb2c7d1aSMickaël Salaün 9cb2c7d1aSMickaël Salaün #ifndef _SECURITY_LANDLOCK_FS_H 10cb2c7d1aSMickaël Salaün #define _SECURITY_LANDLOCK_FS_H 11cb2c7d1aSMickaël Salaün 12cb2c7d1aSMickaël Salaün #include <linux/fs.h> 13cb2c7d1aSMickaël Salaün #include <linux/init.h> 14cb2c7d1aSMickaël Salaün #include <linux/rcupdate.h> 15cb2c7d1aSMickaël Salaün 16cb2c7d1aSMickaël Salaün #include "ruleset.h" 17cb2c7d1aSMickaël Salaün #include "setup.h" 18cb2c7d1aSMickaël Salaün 19cb2c7d1aSMickaël Salaün /** 20cb2c7d1aSMickaël Salaün * struct landlock_inode_security - Inode security blob 21cb2c7d1aSMickaël Salaün * 22cb2c7d1aSMickaël Salaün * Enable to reference a &struct landlock_object tied to an inode (i.e. 23cb2c7d1aSMickaël Salaün * underlying object). 24cb2c7d1aSMickaël Salaün */ 25cb2c7d1aSMickaël Salaün struct landlock_inode_security { 26cb2c7d1aSMickaël Salaün /** 27cb2c7d1aSMickaël Salaün * @object: Weak pointer to an allocated object. All assignments of a 28cb2c7d1aSMickaël Salaün * new object are protected by the underlying inode->i_lock. However, 29cb2c7d1aSMickaël Salaün * atomically disassociating @object from the inode is only protected 30cb2c7d1aSMickaël Salaün * by @object->lock, from the time @object's usage refcount drops to 31cb2c7d1aSMickaël Salaün * zero to the time this pointer is nulled out (cf. release_inode() and 32cb2c7d1aSMickaël Salaün * hook_sb_delete()). Indeed, such disassociation doesn't require 33cb2c7d1aSMickaël Salaün * inode->i_lock thanks to the careful rcu_access_pointer() check 34cb2c7d1aSMickaël Salaün * performed by get_inode_object(). 35cb2c7d1aSMickaël Salaün */ 36cb2c7d1aSMickaël Salaün struct landlock_object __rcu *object; 37cb2c7d1aSMickaël Salaün }; 38cb2c7d1aSMickaël Salaün 39cb2c7d1aSMickaël Salaün /** 40*b9f5ce27SGünther Noack * struct landlock_file_security - File security blob 41*b9f5ce27SGünther Noack * 42*b9f5ce27SGünther Noack * This information is populated when opening a file in hook_file_open, and 43*b9f5ce27SGünther Noack * tracks the relevant Landlock access rights that were available at the time 44*b9f5ce27SGünther Noack * of opening the file. Other LSM hooks use these rights in order to authorize 45*b9f5ce27SGünther Noack * operations on already opened files. 46*b9f5ce27SGünther Noack */ 47*b9f5ce27SGünther Noack struct landlock_file_security { 48*b9f5ce27SGünther Noack /** 49*b9f5ce27SGünther Noack * @allowed_access: Access rights that were available at the time of 50*b9f5ce27SGünther Noack * opening the file. This is not necessarily the full set of access 51*b9f5ce27SGünther Noack * rights available at that time, but it's the necessary subset as 52*b9f5ce27SGünther Noack * needed to authorize later operations on the open file. 53*b9f5ce27SGünther Noack */ 54*b9f5ce27SGünther Noack access_mask_t allowed_access; 55*b9f5ce27SGünther Noack }; 56*b9f5ce27SGünther Noack 57*b9f5ce27SGünther Noack /** 58cb2c7d1aSMickaël Salaün * struct landlock_superblock_security - Superblock security blob 59cb2c7d1aSMickaël Salaün * 60cb2c7d1aSMickaël Salaün * Enable hook_sb_delete() to wait for concurrent calls to release_inode(). 61cb2c7d1aSMickaël Salaün */ 62cb2c7d1aSMickaël Salaün struct landlock_superblock_security { 63cb2c7d1aSMickaël Salaün /** 64cb2c7d1aSMickaël Salaün * @inode_refs: Number of pending inodes (from this superblock) that 65cb2c7d1aSMickaël Salaün * are being released by release_inode(). 66cb2c7d1aSMickaël Salaün * Cf. struct super_block->s_fsnotify_inode_refs . 67cb2c7d1aSMickaël Salaün */ 68cb2c7d1aSMickaël Salaün atomic_long_t inode_refs; 69cb2c7d1aSMickaël Salaün }; 70cb2c7d1aSMickaël Salaün 71*b9f5ce27SGünther Noack static inline struct landlock_file_security * landlock_file(const struct file * const file)72*b9f5ce27SGünther Noacklandlock_file(const struct file *const file) 73*b9f5ce27SGünther Noack { 74*b9f5ce27SGünther Noack return file->f_security + landlock_blob_sizes.lbs_file; 75*b9f5ce27SGünther Noack } 76*b9f5ce27SGünther Noack 7706a1c40aSMickaël Salaün static inline struct landlock_inode_security * landlock_inode(const struct inode * const inode)7806a1c40aSMickaël Salaünlandlock_inode(const struct inode *const inode) 79cb2c7d1aSMickaël Salaün { 80cb2c7d1aSMickaël Salaün return inode->i_security + landlock_blob_sizes.lbs_inode; 81cb2c7d1aSMickaël Salaün } 82cb2c7d1aSMickaël Salaün 8306a1c40aSMickaël Salaün static inline struct landlock_superblock_security * landlock_superblock(const struct super_block * const superblock)8406a1c40aSMickaël Salaünlandlock_superblock(const struct super_block *const superblock) 85cb2c7d1aSMickaël Salaün { 86cb2c7d1aSMickaël Salaün return superblock->s_security + landlock_blob_sizes.lbs_superblock; 87cb2c7d1aSMickaël Salaün } 88cb2c7d1aSMickaël Salaün 89cb2c7d1aSMickaël Salaün __init void landlock_add_fs_hooks(void); 90cb2c7d1aSMickaël Salaün 91cb2c7d1aSMickaël Salaün int landlock_append_fs_rule(struct landlock_ruleset *const ruleset, 9206a1c40aSMickaël Salaün const struct path *const path, 935f2ff33eSMickaël Salaün access_mask_t access_hierarchy); 94cb2c7d1aSMickaël Salaün 95cb2c7d1aSMickaël Salaün #endif /* _SECURITY_LANDLOCK_FS_H */ 96