18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * inode.c - securityfs 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Based on fs/debugfs/inode.c which had the following copyright notice: 88c2ecf20Sopenharmony_ci * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> 98c2ecf20Sopenharmony_ci * Copyright (C) 2004 IBM Inc. 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/* #define DEBUG */ 138c2ecf20Sopenharmony_ci#include <linux/sysfs.h> 148c2ecf20Sopenharmony_ci#include <linux/kobject.h> 158c2ecf20Sopenharmony_ci#include <linux/fs.h> 168c2ecf20Sopenharmony_ci#include <linux/fs_context.h> 178c2ecf20Sopenharmony_ci#include <linux/mount.h> 188c2ecf20Sopenharmony_ci#include <linux/pagemap.h> 198c2ecf20Sopenharmony_ci#include <linux/init.h> 208c2ecf20Sopenharmony_ci#include <linux/namei.h> 218c2ecf20Sopenharmony_ci#include <linux/security.h> 228c2ecf20Sopenharmony_ci#include <linux/lsm_hooks.h> 238c2ecf20Sopenharmony_ci#include <linux/magic.h> 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistatic struct vfsmount *mount; 268c2ecf20Sopenharmony_cistatic int mount_count; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistatic void securityfs_free_inode(struct inode *inode) 298c2ecf20Sopenharmony_ci{ 308c2ecf20Sopenharmony_ci if (S_ISLNK(inode->i_mode)) 318c2ecf20Sopenharmony_ci kfree(inode->i_link); 328c2ecf20Sopenharmony_ci free_inode_nonrcu(inode); 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic const struct super_operations securityfs_super_operations = { 368c2ecf20Sopenharmony_ci .statfs = simple_statfs, 378c2ecf20Sopenharmony_ci .free_inode = securityfs_free_inode, 388c2ecf20Sopenharmony_ci}; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistatic int securityfs_fill_super(struct super_block *sb, struct fs_context *fc) 418c2ecf20Sopenharmony_ci{ 428c2ecf20Sopenharmony_ci static const struct tree_descr files[] = {{""}}; 438c2ecf20Sopenharmony_ci int error; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci error = simple_fill_super(sb, SECURITYFS_MAGIC, files); 468c2ecf20Sopenharmony_ci if (error) 478c2ecf20Sopenharmony_ci return error; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci sb->s_op = &securityfs_super_operations; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci return 0; 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistatic int securityfs_get_tree(struct fs_context *fc) 558c2ecf20Sopenharmony_ci{ 568c2ecf20Sopenharmony_ci return get_tree_single(fc, securityfs_fill_super); 578c2ecf20Sopenharmony_ci} 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic const struct fs_context_operations securityfs_context_ops = { 608c2ecf20Sopenharmony_ci .get_tree = securityfs_get_tree, 618c2ecf20Sopenharmony_ci}; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic int securityfs_init_fs_context(struct fs_context *fc) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci fc->ops = &securityfs_context_ops; 668c2ecf20Sopenharmony_ci return 0; 678c2ecf20Sopenharmony_ci} 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistatic struct file_system_type fs_type = { 708c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 718c2ecf20Sopenharmony_ci .name = "securityfs", 728c2ecf20Sopenharmony_ci .init_fs_context = securityfs_init_fs_context, 738c2ecf20Sopenharmony_ci .kill_sb = kill_litter_super, 748c2ecf20Sopenharmony_ci}; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci/** 778c2ecf20Sopenharmony_ci * securityfs_create_dentry - create a dentry in the securityfs filesystem 788c2ecf20Sopenharmony_ci * 798c2ecf20Sopenharmony_ci * @name: a pointer to a string containing the name of the file to create. 808c2ecf20Sopenharmony_ci * @mode: the permission that the file should have 818c2ecf20Sopenharmony_ci * @parent: a pointer to the parent dentry for this file. This should be a 828c2ecf20Sopenharmony_ci * directory dentry if set. If this parameter is %NULL, then the 838c2ecf20Sopenharmony_ci * file will be created in the root of the securityfs filesystem. 848c2ecf20Sopenharmony_ci * @data: a pointer to something that the caller will want to get to later 858c2ecf20Sopenharmony_ci * on. The inode.i_private pointer will point to this value on 868c2ecf20Sopenharmony_ci * the open() call. 878c2ecf20Sopenharmony_ci * @fops: a pointer to a struct file_operations that should be used for 888c2ecf20Sopenharmony_ci * this file. 898c2ecf20Sopenharmony_ci * @iops: a point to a struct of inode_operations that should be used for 908c2ecf20Sopenharmony_ci * this file/dir 918c2ecf20Sopenharmony_ci * 928c2ecf20Sopenharmony_ci * This is the basic "create a file/dir/symlink" function for 938c2ecf20Sopenharmony_ci * securityfs. It allows for a wide range of flexibility in creating 948c2ecf20Sopenharmony_ci * a file, or a directory (if you want to create a directory, the 958c2ecf20Sopenharmony_ci * securityfs_create_dir() function is recommended to be used 968c2ecf20Sopenharmony_ci * instead). 978c2ecf20Sopenharmony_ci * 988c2ecf20Sopenharmony_ci * This function returns a pointer to a dentry if it succeeds. This 998c2ecf20Sopenharmony_ci * pointer must be passed to the securityfs_remove() function when the 1008c2ecf20Sopenharmony_ci * file is to be removed (no automatic cleanup happens if your module 1018c2ecf20Sopenharmony_ci * is unloaded, you are responsible here). If an error occurs, the 1028c2ecf20Sopenharmony_ci * function will return the error value (via ERR_PTR). 1038c2ecf20Sopenharmony_ci * 1048c2ecf20Sopenharmony_ci * If securityfs is not enabled in the kernel, the value %-ENODEV is 1058c2ecf20Sopenharmony_ci * returned. 1068c2ecf20Sopenharmony_ci */ 1078c2ecf20Sopenharmony_cistatic struct dentry *securityfs_create_dentry(const char *name, umode_t mode, 1088c2ecf20Sopenharmony_ci struct dentry *parent, void *data, 1098c2ecf20Sopenharmony_ci const struct file_operations *fops, 1108c2ecf20Sopenharmony_ci const struct inode_operations *iops) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci struct dentry *dentry; 1138c2ecf20Sopenharmony_ci struct inode *dir, *inode; 1148c2ecf20Sopenharmony_ci int error; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci if (!(mode & S_IFMT)) 1178c2ecf20Sopenharmony_ci mode = (mode & S_IALLUGO) | S_IFREG; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci pr_debug("securityfs: creating file '%s'\n",name); 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci error = simple_pin_fs(&fs_type, &mount, &mount_count); 1228c2ecf20Sopenharmony_ci if (error) 1238c2ecf20Sopenharmony_ci return ERR_PTR(error); 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci if (!parent) 1268c2ecf20Sopenharmony_ci parent = mount->mnt_root; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci dir = d_inode(parent); 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci inode_lock(dir); 1318c2ecf20Sopenharmony_ci dentry = lookup_one_len(name, parent, strlen(name)); 1328c2ecf20Sopenharmony_ci if (IS_ERR(dentry)) 1338c2ecf20Sopenharmony_ci goto out; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci if (d_really_is_positive(dentry)) { 1368c2ecf20Sopenharmony_ci error = -EEXIST; 1378c2ecf20Sopenharmony_ci goto out1; 1388c2ecf20Sopenharmony_ci } 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci inode = new_inode(dir->i_sb); 1418c2ecf20Sopenharmony_ci if (!inode) { 1428c2ecf20Sopenharmony_ci error = -ENOMEM; 1438c2ecf20Sopenharmony_ci goto out1; 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci inode->i_ino = get_next_ino(); 1478c2ecf20Sopenharmony_ci inode->i_mode = mode; 1488c2ecf20Sopenharmony_ci inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); 1498c2ecf20Sopenharmony_ci inode->i_private = data; 1508c2ecf20Sopenharmony_ci if (S_ISDIR(mode)) { 1518c2ecf20Sopenharmony_ci inode->i_op = &simple_dir_inode_operations; 1528c2ecf20Sopenharmony_ci inode->i_fop = &simple_dir_operations; 1538c2ecf20Sopenharmony_ci inc_nlink(inode); 1548c2ecf20Sopenharmony_ci inc_nlink(dir); 1558c2ecf20Sopenharmony_ci } else if (S_ISLNK(mode)) { 1568c2ecf20Sopenharmony_ci inode->i_op = iops ? iops : &simple_symlink_inode_operations; 1578c2ecf20Sopenharmony_ci inode->i_link = data; 1588c2ecf20Sopenharmony_ci } else { 1598c2ecf20Sopenharmony_ci inode->i_fop = fops; 1608c2ecf20Sopenharmony_ci } 1618c2ecf20Sopenharmony_ci d_instantiate(dentry, inode); 1628c2ecf20Sopenharmony_ci dget(dentry); 1638c2ecf20Sopenharmony_ci inode_unlock(dir); 1648c2ecf20Sopenharmony_ci return dentry; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ciout1: 1678c2ecf20Sopenharmony_ci dput(dentry); 1688c2ecf20Sopenharmony_ci dentry = ERR_PTR(error); 1698c2ecf20Sopenharmony_ciout: 1708c2ecf20Sopenharmony_ci inode_unlock(dir); 1718c2ecf20Sopenharmony_ci simple_release_fs(&mount, &mount_count); 1728c2ecf20Sopenharmony_ci return dentry; 1738c2ecf20Sopenharmony_ci} 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci/** 1768c2ecf20Sopenharmony_ci * securityfs_create_file - create a file in the securityfs filesystem 1778c2ecf20Sopenharmony_ci * 1788c2ecf20Sopenharmony_ci * @name: a pointer to a string containing the name of the file to create. 1798c2ecf20Sopenharmony_ci * @mode: the permission that the file should have 1808c2ecf20Sopenharmony_ci * @parent: a pointer to the parent dentry for this file. This should be a 1818c2ecf20Sopenharmony_ci * directory dentry if set. If this parameter is %NULL, then the 1828c2ecf20Sopenharmony_ci * file will be created in the root of the securityfs filesystem. 1838c2ecf20Sopenharmony_ci * @data: a pointer to something that the caller will want to get to later 1848c2ecf20Sopenharmony_ci * on. The inode.i_private pointer will point to this value on 1858c2ecf20Sopenharmony_ci * the open() call. 1868c2ecf20Sopenharmony_ci * @fops: a pointer to a struct file_operations that should be used for 1878c2ecf20Sopenharmony_ci * this file. 1888c2ecf20Sopenharmony_ci * 1898c2ecf20Sopenharmony_ci * This function creates a file in securityfs with the given @name. 1908c2ecf20Sopenharmony_ci * 1918c2ecf20Sopenharmony_ci * This function returns a pointer to a dentry if it succeeds. This 1928c2ecf20Sopenharmony_ci * pointer must be passed to the securityfs_remove() function when the file is 1938c2ecf20Sopenharmony_ci * to be removed (no automatic cleanup happens if your module is unloaded, 1948c2ecf20Sopenharmony_ci * you are responsible here). If an error occurs, the function will return 1958c2ecf20Sopenharmony_ci * the error value (via ERR_PTR). 1968c2ecf20Sopenharmony_ci * 1978c2ecf20Sopenharmony_ci * If securityfs is not enabled in the kernel, the value %-ENODEV is 1988c2ecf20Sopenharmony_ci * returned. 1998c2ecf20Sopenharmony_ci */ 2008c2ecf20Sopenharmony_cistruct dentry *securityfs_create_file(const char *name, umode_t mode, 2018c2ecf20Sopenharmony_ci struct dentry *parent, void *data, 2028c2ecf20Sopenharmony_ci const struct file_operations *fops) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci return securityfs_create_dentry(name, mode, parent, data, fops, NULL); 2058c2ecf20Sopenharmony_ci} 2068c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(securityfs_create_file); 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci/** 2098c2ecf20Sopenharmony_ci * securityfs_create_dir - create a directory in the securityfs filesystem 2108c2ecf20Sopenharmony_ci * 2118c2ecf20Sopenharmony_ci * @name: a pointer to a string containing the name of the directory to 2128c2ecf20Sopenharmony_ci * create. 2138c2ecf20Sopenharmony_ci * @parent: a pointer to the parent dentry for this file. This should be a 2148c2ecf20Sopenharmony_ci * directory dentry if set. If this parameter is %NULL, then the 2158c2ecf20Sopenharmony_ci * directory will be created in the root of the securityfs filesystem. 2168c2ecf20Sopenharmony_ci * 2178c2ecf20Sopenharmony_ci * This function creates a directory in securityfs with the given @name. 2188c2ecf20Sopenharmony_ci * 2198c2ecf20Sopenharmony_ci * This function returns a pointer to a dentry if it succeeds. This 2208c2ecf20Sopenharmony_ci * pointer must be passed to the securityfs_remove() function when the file is 2218c2ecf20Sopenharmony_ci * to be removed (no automatic cleanup happens if your module is unloaded, 2228c2ecf20Sopenharmony_ci * you are responsible here). If an error occurs, the function will return 2238c2ecf20Sopenharmony_ci * the error value (via ERR_PTR). 2248c2ecf20Sopenharmony_ci * 2258c2ecf20Sopenharmony_ci * If securityfs is not enabled in the kernel, the value %-ENODEV is 2268c2ecf20Sopenharmony_ci * returned. 2278c2ecf20Sopenharmony_ci */ 2288c2ecf20Sopenharmony_cistruct dentry *securityfs_create_dir(const char *name, struct dentry *parent) 2298c2ecf20Sopenharmony_ci{ 2308c2ecf20Sopenharmony_ci return securityfs_create_file(name, S_IFDIR | 0755, parent, NULL, NULL); 2318c2ecf20Sopenharmony_ci} 2328c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(securityfs_create_dir); 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci/** 2358c2ecf20Sopenharmony_ci * securityfs_create_symlink - create a symlink in the securityfs filesystem 2368c2ecf20Sopenharmony_ci * 2378c2ecf20Sopenharmony_ci * @name: a pointer to a string containing the name of the symlink to 2388c2ecf20Sopenharmony_ci * create. 2398c2ecf20Sopenharmony_ci * @parent: a pointer to the parent dentry for the symlink. This should be a 2408c2ecf20Sopenharmony_ci * directory dentry if set. If this parameter is %NULL, then the 2418c2ecf20Sopenharmony_ci * directory will be created in the root of the securityfs filesystem. 2428c2ecf20Sopenharmony_ci * @target: a pointer to a string containing the name of the symlink's target. 2438c2ecf20Sopenharmony_ci * If this parameter is %NULL, then the @iops parameter needs to be 2448c2ecf20Sopenharmony_ci * setup to handle .readlink and .get_link inode_operations. 2458c2ecf20Sopenharmony_ci * @iops: a pointer to the struct inode_operations to use for the symlink. If 2468c2ecf20Sopenharmony_ci * this parameter is %NULL, then the default simple_symlink_inode 2478c2ecf20Sopenharmony_ci * operations will be used. 2488c2ecf20Sopenharmony_ci * 2498c2ecf20Sopenharmony_ci * This function creates a symlink in securityfs with the given @name. 2508c2ecf20Sopenharmony_ci * 2518c2ecf20Sopenharmony_ci * This function returns a pointer to a dentry if it succeeds. This 2528c2ecf20Sopenharmony_ci * pointer must be passed to the securityfs_remove() function when the file is 2538c2ecf20Sopenharmony_ci * to be removed (no automatic cleanup happens if your module is unloaded, 2548c2ecf20Sopenharmony_ci * you are responsible here). If an error occurs, the function will return 2558c2ecf20Sopenharmony_ci * the error value (via ERR_PTR). 2568c2ecf20Sopenharmony_ci * 2578c2ecf20Sopenharmony_ci * If securityfs is not enabled in the kernel, the value %-ENODEV is 2588c2ecf20Sopenharmony_ci * returned. 2598c2ecf20Sopenharmony_ci */ 2608c2ecf20Sopenharmony_cistruct dentry *securityfs_create_symlink(const char *name, 2618c2ecf20Sopenharmony_ci struct dentry *parent, 2628c2ecf20Sopenharmony_ci const char *target, 2638c2ecf20Sopenharmony_ci const struct inode_operations *iops) 2648c2ecf20Sopenharmony_ci{ 2658c2ecf20Sopenharmony_ci struct dentry *dent; 2668c2ecf20Sopenharmony_ci char *link = NULL; 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci if (target) { 2698c2ecf20Sopenharmony_ci link = kstrdup(target, GFP_KERNEL); 2708c2ecf20Sopenharmony_ci if (!link) 2718c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 2728c2ecf20Sopenharmony_ci } 2738c2ecf20Sopenharmony_ci dent = securityfs_create_dentry(name, S_IFLNK | 0444, parent, 2748c2ecf20Sopenharmony_ci link, NULL, iops); 2758c2ecf20Sopenharmony_ci if (IS_ERR(dent)) 2768c2ecf20Sopenharmony_ci kfree(link); 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci return dent; 2798c2ecf20Sopenharmony_ci} 2808c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(securityfs_create_symlink); 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci/** 2838c2ecf20Sopenharmony_ci * securityfs_remove - removes a file or directory from the securityfs filesystem 2848c2ecf20Sopenharmony_ci * 2858c2ecf20Sopenharmony_ci * @dentry: a pointer to a the dentry of the file or directory to be removed. 2868c2ecf20Sopenharmony_ci * 2878c2ecf20Sopenharmony_ci * This function removes a file or directory in securityfs that was previously 2888c2ecf20Sopenharmony_ci * created with a call to another securityfs function (like 2898c2ecf20Sopenharmony_ci * securityfs_create_file() or variants thereof.) 2908c2ecf20Sopenharmony_ci * 2918c2ecf20Sopenharmony_ci * This function is required to be called in order for the file to be 2928c2ecf20Sopenharmony_ci * removed. No automatic cleanup of files will happen when a module is 2938c2ecf20Sopenharmony_ci * removed; you are responsible here. 2948c2ecf20Sopenharmony_ci */ 2958c2ecf20Sopenharmony_civoid securityfs_remove(struct dentry *dentry) 2968c2ecf20Sopenharmony_ci{ 2978c2ecf20Sopenharmony_ci struct inode *dir; 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci if (!dentry || IS_ERR(dentry)) 3008c2ecf20Sopenharmony_ci return; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci dir = d_inode(dentry->d_parent); 3038c2ecf20Sopenharmony_ci inode_lock(dir); 3048c2ecf20Sopenharmony_ci if (simple_positive(dentry)) { 3058c2ecf20Sopenharmony_ci if (d_is_dir(dentry)) 3068c2ecf20Sopenharmony_ci simple_rmdir(dir, dentry); 3078c2ecf20Sopenharmony_ci else 3088c2ecf20Sopenharmony_ci simple_unlink(dir, dentry); 3098c2ecf20Sopenharmony_ci dput(dentry); 3108c2ecf20Sopenharmony_ci } 3118c2ecf20Sopenharmony_ci inode_unlock(dir); 3128c2ecf20Sopenharmony_ci simple_release_fs(&mount, &mount_count); 3138c2ecf20Sopenharmony_ci} 3148c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(securityfs_remove); 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci#ifdef CONFIG_SECURITY 3178c2ecf20Sopenharmony_cistatic struct dentry *lsm_dentry; 3188c2ecf20Sopenharmony_cistatic ssize_t lsm_read(struct file *filp, char __user *buf, size_t count, 3198c2ecf20Sopenharmony_ci loff_t *ppos) 3208c2ecf20Sopenharmony_ci{ 3218c2ecf20Sopenharmony_ci return simple_read_from_buffer(buf, count, ppos, lsm_names, 3228c2ecf20Sopenharmony_ci strlen(lsm_names)); 3238c2ecf20Sopenharmony_ci} 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_cistatic const struct file_operations lsm_ops = { 3268c2ecf20Sopenharmony_ci .read = lsm_read, 3278c2ecf20Sopenharmony_ci .llseek = generic_file_llseek, 3288c2ecf20Sopenharmony_ci}; 3298c2ecf20Sopenharmony_ci#endif 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_cistatic int __init securityfs_init(void) 3328c2ecf20Sopenharmony_ci{ 3338c2ecf20Sopenharmony_ci int retval; 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci retval = sysfs_create_mount_point(kernel_kobj, "security"); 3368c2ecf20Sopenharmony_ci if (retval) 3378c2ecf20Sopenharmony_ci return retval; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci retval = register_filesystem(&fs_type); 3408c2ecf20Sopenharmony_ci if (retval) { 3418c2ecf20Sopenharmony_ci sysfs_remove_mount_point(kernel_kobj, "security"); 3428c2ecf20Sopenharmony_ci return retval; 3438c2ecf20Sopenharmony_ci } 3448c2ecf20Sopenharmony_ci#ifdef CONFIG_SECURITY 3458c2ecf20Sopenharmony_ci lsm_dentry = securityfs_create_file("lsm", 0444, NULL, NULL, 3468c2ecf20Sopenharmony_ci &lsm_ops); 3478c2ecf20Sopenharmony_ci#endif 3488c2ecf20Sopenharmony_ci return 0; 3498c2ecf20Sopenharmony_ci} 3508c2ecf20Sopenharmony_cicore_initcall(securityfs_init); 351