// SPDX-License-Identifier: GPL-2.0-only1/*2* inode.c - securityfs3*4* Copyright (C) 2005 Greg Kroah-Hartman <[email protected]>5*6* Based on fs/debugfs/inode.c which had the following copyright notice:7* Copyright (C) 2004 Greg Kroah-Hartman <[email protected]>8* Copyright (C) 2004 IBM Inc.9*/1011/* #define DEBUG */12#include <linux/sysfs.h>13#include <linux/kobject.h>14#include <linux/fs.h>15#include <linux/fs_context.h>16#include <linux/mount.h>17#include <linux/pagemap.h>18#include <linux/init.h>19#include <linux/namei.h>20#include <linux/security.h>21#include <linux/lsm_hooks.h>22#include <linux/magic.h>2324#include "lsm.h"2526static struct vfsmount *mount;27static int mount_count;2829static void securityfs_free_inode(struct inode *inode)30{31if (S_ISLNK(inode->i_mode))32kfree(inode->i_link);33free_inode_nonrcu(inode);34}3536static const struct super_operations securityfs_super_operations = {37.statfs = simple_statfs,38.free_inode = securityfs_free_inode,39};4041static int securityfs_fill_super(struct super_block *sb, struct fs_context *fc)42{43static const struct tree_descr files[] = {{""}};44int error;4546error = simple_fill_super(sb, SECURITYFS_MAGIC, files);47if (error)48return error;4950sb->s_op = &securityfs_super_operations;5152return 0;53}5455static int securityfs_get_tree(struct fs_context *fc)56{57return get_tree_single(fc, securityfs_fill_super);58}5960static const struct fs_context_operations securityfs_context_ops = {61.get_tree = securityfs_get_tree,62};6364static int securityfs_init_fs_context(struct fs_context *fc)65{66fc->ops = &securityfs_context_ops;67return 0;68}6970static struct file_system_type fs_type = {71.owner = THIS_MODULE,72.name = "securityfs",73.init_fs_context = securityfs_init_fs_context,74.kill_sb = kill_anon_super,75};7677/**78* securityfs_create_dentry - create a dentry in the securityfs filesystem79*80* @name: a pointer to a string containing the name of the file to create.81* @mode: the permission that the file should have82* @parent: a pointer to the parent dentry for this file. This should be a83* directory dentry if set. If this parameter is %NULL, then the84* file will be created in the root of the securityfs filesystem.85* @data: a pointer to something that the caller will want to get to later86* on. The inode.i_private pointer will point to this value on87* the open() call.88* @fops: a pointer to a struct file_operations that should be used for89* this file.90* @iops: a point to a struct of inode_operations that should be used for91* this file/dir92*93* This is the basic "create a file/dir/symlink" function for94* securityfs. It allows for a wide range of flexibility in creating95* a file, or a directory (if you want to create a directory, the96* securityfs_create_dir() function is recommended to be used97* instead).98*99* This function returns a pointer to a dentry if it succeeds. This100* pointer must be passed to the securityfs_remove() function when the101* file is to be removed (no automatic cleanup happens if your module102* is unloaded, you are responsible here). If an error occurs, the103* function will return the error value (via ERR_PTR).104*105* If securityfs is not enabled in the kernel, the value %-ENODEV is106* returned.107*/108static struct dentry *securityfs_create_dentry(const char *name, umode_t mode,109struct dentry *parent, void *data,110const struct file_operations *fops,111const struct inode_operations *iops)112{113struct dentry *dentry;114struct inode *dir, *inode;115int error;116bool pinned = false;117118if (!(mode & S_IFMT))119mode = (mode & S_IALLUGO) | S_IFREG;120121pr_debug("securityfs: creating file '%s'\n",name);122123if (!parent) {124error = simple_pin_fs(&fs_type, &mount, &mount_count);125if (error)126return ERR_PTR(error);127pinned = true;128parent = mount->mnt_root;129}130131inode = new_inode(parent->d_sb);132if (unlikely(!inode)) {133dentry = ERR_PTR(-ENOMEM);134goto out;135}136137dir = d_inode(parent);138139dentry = simple_start_creating(parent, name);140if (IS_ERR(dentry)) {141iput(inode);142goto out;143}144inode->i_ino = get_next_ino();145inode->i_mode = mode;146simple_inode_init_ts(inode);147inode->i_private = data;148if (S_ISDIR(mode)) {149inode->i_op = &simple_dir_inode_operations;150inode->i_fop = &simple_dir_operations;151inc_nlink(inode);152inc_nlink(dir);153} else if (S_ISLNK(mode)) {154inode->i_op = iops ? iops : &simple_symlink_inode_operations;155inode->i_link = data;156} else {157inode->i_fop = fops;158}159d_make_persistent(dentry, inode);160simple_done_creating(dentry);161return dentry; // borrowed162163out:164if (pinned)165simple_release_fs(&mount, &mount_count);166return dentry;167}168169/**170* securityfs_create_file - create a file in the securityfs filesystem171*172* @name: a pointer to a string containing the name of the file to create.173* @mode: the permission that the file should have174* @parent: a pointer to the parent dentry for this file. This should be a175* directory dentry if set. If this parameter is %NULL, then the176* file will be created in the root of the securityfs filesystem.177* @data: a pointer to something that the caller will want to get to later178* on. The inode.i_private pointer will point to this value on179* the open() call.180* @fops: a pointer to a struct file_operations that should be used for181* this file.182*183* This function creates a file in securityfs with the given @name.184*185* This function returns a pointer to a dentry if it succeeds. This186* pointer must be passed to the securityfs_remove() function when the file is187* to be removed (no automatic cleanup happens if your module is unloaded,188* you are responsible here). If an error occurs, the function will return189* the error value (via ERR_PTR).190*191* If securityfs is not enabled in the kernel, the value %-ENODEV is192* returned.193*/194struct dentry *securityfs_create_file(const char *name, umode_t mode,195struct dentry *parent, void *data,196const struct file_operations *fops)197{198return securityfs_create_dentry(name, mode, parent, data, fops, NULL);199}200EXPORT_SYMBOL_GPL(securityfs_create_file);201202/**203* securityfs_create_dir - create a directory in the securityfs filesystem204*205* @name: a pointer to a string containing the name of the directory to206* create.207* @parent: a pointer to the parent dentry for this file. This should be a208* directory dentry if set. If this parameter is %NULL, then the209* directory will be created in the root of the securityfs filesystem.210*211* This function creates a directory in securityfs with the given @name.212*213* This function returns a pointer to a dentry if it succeeds. This214* pointer must be passed to the securityfs_remove() function when the file is215* to be removed (no automatic cleanup happens if your module is unloaded,216* you are responsible here). If an error occurs, the function will return217* the error value (via ERR_PTR).218*219* If securityfs is not enabled in the kernel, the value %-ENODEV is220* returned.221*/222struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)223{224return securityfs_create_file(name, S_IFDIR | 0755, parent, NULL, NULL);225}226EXPORT_SYMBOL_GPL(securityfs_create_dir);227228/**229* securityfs_create_symlink - create a symlink in the securityfs filesystem230*231* @name: a pointer to a string containing the name of the symlink to232* create.233* @parent: a pointer to the parent dentry for the symlink. This should be a234* directory dentry if set. If this parameter is %NULL, then the235* directory will be created in the root of the securityfs filesystem.236* @target: a pointer to a string containing the name of the symlink's target.237* If this parameter is %NULL, then the @iops parameter needs to be238* setup to handle .readlink and .get_link inode_operations.239* @iops: a pointer to the struct inode_operations to use for the symlink. If240* this parameter is %NULL, then the default simple_symlink_inode241* operations will be used.242*243* This function creates a symlink in securityfs with the given @name.244*245* This function returns a pointer to a dentry if it succeeds. This246* pointer must be passed to the securityfs_remove() function when the file is247* to be removed (no automatic cleanup happens if your module is unloaded,248* you are responsible here). If an error occurs, the function will return249* the error value (via ERR_PTR).250*251* If securityfs is not enabled in the kernel, the value %-ENODEV is252* returned.253*/254struct dentry *securityfs_create_symlink(const char *name,255struct dentry *parent,256const char *target,257const struct inode_operations *iops)258{259struct dentry *dent;260char *link = NULL;261262if (target) {263link = kstrdup(target, GFP_KERNEL);264if (!link)265return ERR_PTR(-ENOMEM);266}267dent = securityfs_create_dentry(name, S_IFLNK | 0444, parent,268link, NULL, iops);269if (IS_ERR(dent))270kfree(link);271272return dent;273}274EXPORT_SYMBOL_GPL(securityfs_create_symlink);275276static void remove_one(struct dentry *victim)277{278if (victim->d_parent == victim->d_sb->s_root)279simple_release_fs(&mount, &mount_count);280}281282/**283* securityfs_remove - removes a file or directory from the securityfs filesystem284*285* @dentry: a pointer to a the dentry of the file or directory to be removed.286*287* This function removes a file or directory in securityfs that was previously288* created with a call to another securityfs function (like289* securityfs_create_file() or variants thereof.)290*291* This function is required to be called in order for the file to be292* removed. No automatic cleanup of files will happen when a module is293* removed; you are responsible here.294*295* AV: when applied to directory it will take all children out; no need to call296* it for descendents if ancestor is getting killed.297*/298void securityfs_remove(struct dentry *dentry)299{300if (IS_ERR_OR_NULL(dentry))301return;302303simple_pin_fs(&fs_type, &mount, &mount_count);304simple_recursive_removal(dentry, remove_one);305simple_release_fs(&mount, &mount_count);306}307EXPORT_SYMBOL_GPL(securityfs_remove);308309#ifdef CONFIG_SECURITY310#include <linux/spinlock.h>311312static struct dentry *lsm_dentry;313314static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count,315loff_t *ppos)316{317int i;318static char *str;319static size_t len;320static DEFINE_SPINLOCK(lock);321322/* NOTE: we never free or modify the string once it is set */323324if (unlikely(!str || !len)) {325char *str_tmp;326size_t len_tmp = 0;327328for (i = 0; i < lsm_active_cnt; i++)329/* the '+ 1' accounts for either a comma or a NUL */330len_tmp += strlen(lsm_idlist[i]->name) + 1;331332str_tmp = kmalloc(len_tmp, GFP_KERNEL);333if (!str_tmp)334return -ENOMEM;335str_tmp[0] = '\0';336337for (i = 0; i < lsm_active_cnt; i++) {338if (i > 0)339strcat(str_tmp, ",");340strcat(str_tmp, lsm_idlist[i]->name);341}342343spin_lock(&lock);344if (!str) {345str = str_tmp;346len = len_tmp - 1;347} else348kfree(str_tmp);349spin_unlock(&lock);350}351352return simple_read_from_buffer(buf, count, ppos, str, len);353}354355static const struct file_operations lsm_ops = {356.read = lsm_read,357.llseek = generic_file_llseek,358};359#endif360361int __init securityfs_init(void)362{363int retval;364365retval = sysfs_create_mount_point(kernel_kobj, "security");366if (retval)367return retval;368369retval = register_filesystem(&fs_type);370if (retval) {371sysfs_remove_mount_point(kernel_kobj, "security");372return retval;373}374#ifdef CONFIG_SECURITY375lsm_dentry = securityfs_create_file("lsm", 0444, NULL, NULL,376&lsm_ops);377#endif378return 0;379}380381382