1b67dbf9dSGreg KH /* 2b67dbf9dSGreg KH * inode.c - securityfs 3b67dbf9dSGreg KH * 4b67dbf9dSGreg KH * Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de> 5b67dbf9dSGreg KH * 6b67dbf9dSGreg KH * This program is free software; you can redistribute it and/or 7b67dbf9dSGreg KH * modify it under the terms of the GNU General Public License version 8b67dbf9dSGreg KH * 2 as published by the Free Software Foundation. 9b67dbf9dSGreg KH * 10b67dbf9dSGreg KH * Based on fs/debugfs/inode.c which had the following copyright notice: 11b67dbf9dSGreg KH * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> 12b67dbf9dSGreg KH * Copyright (C) 2004 IBM Inc. 13b67dbf9dSGreg KH */ 14b67dbf9dSGreg KH 15b67dbf9dSGreg KH /* #define DEBUG */ 161072bd67SPaul Gortmaker #include <linux/sysfs.h> 171072bd67SPaul Gortmaker #include <linux/kobject.h> 18b67dbf9dSGreg KH #include <linux/fs.h> 19b67dbf9dSGreg KH #include <linux/mount.h> 20b67dbf9dSGreg KH #include <linux/pagemap.h> 21b67dbf9dSGreg KH #include <linux/init.h> 22b67dbf9dSGreg KH #include <linux/namei.h> 23b67dbf9dSGreg KH #include <linux/security.h> 24d69dece5SCasey Schaufler #include <linux/lsm_hooks.h> 2592562927SMimi Zohar #include <linux/magic.h> 26b67dbf9dSGreg KH 27b67dbf9dSGreg KH static struct vfsmount *mount; 28b67dbf9dSGreg KH static int mount_count; 29b67dbf9dSGreg KH 306623ec7cSJohn Johansen static void securityfs_evict_inode(struct inode *inode) 316623ec7cSJohn Johansen { 326623ec7cSJohn Johansen truncate_inode_pages_final(&inode->i_data); 336623ec7cSJohn Johansen clear_inode(inode); 346623ec7cSJohn Johansen if (S_ISLNK(inode->i_mode)) 356623ec7cSJohn Johansen kfree(inode->i_link); 366623ec7cSJohn Johansen } 376623ec7cSJohn Johansen 386623ec7cSJohn Johansen static const struct super_operations securityfs_super_operations = { 396623ec7cSJohn Johansen .statfs = simple_statfs, 406623ec7cSJohn Johansen .evict_inode = securityfs_evict_inode, 416623ec7cSJohn Johansen }; 426623ec7cSJohn Johansen 43b67dbf9dSGreg KH static int fill_super(struct super_block *sb, void *data, int silent) 44b67dbf9dSGreg KH { 45cda37124SEric Biggers static const struct tree_descr files[] = {{""}}; 466623ec7cSJohn Johansen int error; 47b67dbf9dSGreg KH 486623ec7cSJohn Johansen error = simple_fill_super(sb, SECURITYFS_MAGIC, files); 496623ec7cSJohn Johansen if (error) 506623ec7cSJohn Johansen return error; 516623ec7cSJohn Johansen 526623ec7cSJohn Johansen sb->s_op = &securityfs_super_operations; 536623ec7cSJohn Johansen 546623ec7cSJohn Johansen return 0; 55b67dbf9dSGreg KH } 56b67dbf9dSGreg KH 57fc14f2feSAl Viro static struct dentry *get_sb(struct file_system_type *fs_type, 58b67dbf9dSGreg KH int flags, const char *dev_name, 59fc14f2feSAl Viro void *data) 60b67dbf9dSGreg KH { 61fc14f2feSAl Viro return mount_single(fs_type, flags, data, fill_super); 62b67dbf9dSGreg KH } 63b67dbf9dSGreg KH 64b67dbf9dSGreg KH static struct file_system_type fs_type = { 65b67dbf9dSGreg KH .owner = THIS_MODULE, 66b67dbf9dSGreg KH .name = "securityfs", 67fc14f2feSAl Viro .mount = get_sb, 68b67dbf9dSGreg KH .kill_sb = kill_litter_super, 69b67dbf9dSGreg KH }; 70b67dbf9dSGreg KH 71b67dbf9dSGreg KH /** 726623ec7cSJohn Johansen * securityfs_create_dentry - create a dentry in the securityfs filesystem 73b67dbf9dSGreg KH * 74b67dbf9dSGreg KH * @name: a pointer to a string containing the name of the file to create. 75b67dbf9dSGreg KH * @mode: the permission that the file should have 76b67dbf9dSGreg KH * @parent: a pointer to the parent dentry for this file. This should be a 773f23d815SRandy Dunlap * directory dentry if set. If this parameter is %NULL, then the 78b67dbf9dSGreg KH * file will be created in the root of the securityfs filesystem. 79b67dbf9dSGreg KH * @data: a pointer to something that the caller will want to get to later 808e18e294STheodore Ts'o * on. The inode.i_private pointer will point to this value on 81b67dbf9dSGreg KH * the open() call. 82b67dbf9dSGreg KH * @fops: a pointer to a struct file_operations that should be used for 83b67dbf9dSGreg KH * this file. 846623ec7cSJohn Johansen * @iops: a point to a struct of inode_operations that should be used for 856623ec7cSJohn Johansen * this file/dir 86b67dbf9dSGreg KH * 876623ec7cSJohn Johansen * This is the basic "create a file/dir/symlink" function for 886623ec7cSJohn Johansen * securityfs. It allows for a wide range of flexibility in creating 896623ec7cSJohn Johansen * a file, or a directory (if you want to create a directory, the 906623ec7cSJohn Johansen * securityfs_create_dir() function is recommended to be used 916623ec7cSJohn Johansen * instead). 92b67dbf9dSGreg KH * 933f23d815SRandy Dunlap * This function returns a pointer to a dentry if it succeeds. This 946623ec7cSJohn Johansen * pointer must be passed to the securityfs_remove() function when the 956623ec7cSJohn Johansen * file is to be removed (no automatic cleanup happens if your module 966623ec7cSJohn Johansen * is unloaded, you are responsible here). If an error occurs, the 976623ec7cSJohn Johansen * function will return the error value (via ERR_PTR). 98b67dbf9dSGreg KH * 993f23d815SRandy Dunlap * If securityfs is not enabled in the kernel, the value %-ENODEV is 100faa3aad7SSerge E. Hallyn * returned. 101b67dbf9dSGreg KH */ 1026623ec7cSJohn Johansen static struct dentry *securityfs_create_dentry(const char *name, umode_t mode, 103b67dbf9dSGreg KH struct dentry *parent, void *data, 1046623ec7cSJohn Johansen const struct file_operations *fops, 1056623ec7cSJohn Johansen const struct inode_operations *iops) 106b67dbf9dSGreg KH { 1073e25eb9cSAl Viro struct dentry *dentry; 1083e25eb9cSAl Viro struct inode *dir, *inode; 109b67dbf9dSGreg KH int error; 110b67dbf9dSGreg KH 1116623ec7cSJohn Johansen if (!(mode & S_IFMT)) 1123e25eb9cSAl Viro mode = (mode & S_IALLUGO) | S_IFREG; 1133e25eb9cSAl Viro 114b67dbf9dSGreg KH pr_debug("securityfs: creating file '%s'\n",name); 115b67dbf9dSGreg KH 1161f5ce9e9STrond Myklebust error = simple_pin_fs(&fs_type, &mount, &mount_count); 1173e25eb9cSAl Viro if (error) 1183e25eb9cSAl Viro return ERR_PTR(error); 119b67dbf9dSGreg KH 1203e25eb9cSAl Viro if (!parent) 1213e25eb9cSAl Viro parent = mount->mnt_root; 1223e25eb9cSAl Viro 123ce0b16ddSDavid Howells dir = d_inode(parent); 1243e25eb9cSAl Viro 1255955102cSAl Viro inode_lock(dir); 1263e25eb9cSAl Viro dentry = lookup_one_len(name, parent, strlen(name)); 1273e25eb9cSAl Viro if (IS_ERR(dentry)) 1283e25eb9cSAl Viro goto out; 129b67dbf9dSGreg KH 130ce0b16ddSDavid Howells if (d_really_is_positive(dentry)) { 1313e25eb9cSAl Viro error = -EEXIST; 1323e25eb9cSAl Viro goto out1; 133b67dbf9dSGreg KH } 1343e25eb9cSAl Viro 1353e25eb9cSAl Viro inode = new_inode(dir->i_sb); 1363e25eb9cSAl Viro if (!inode) { 1373e25eb9cSAl Viro error = -ENOMEM; 1383e25eb9cSAl Viro goto out1; 1393e25eb9cSAl Viro } 1403e25eb9cSAl Viro 1413e25eb9cSAl Viro inode->i_ino = get_next_ino(); 1423e25eb9cSAl Viro inode->i_mode = mode; 143078cd827SDeepa Dinamani inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); 1443e25eb9cSAl Viro inode->i_private = data; 1456623ec7cSJohn Johansen if (S_ISDIR(mode)) { 1463e25eb9cSAl Viro inode->i_op = &simple_dir_inode_operations; 1473e25eb9cSAl Viro inode->i_fop = &simple_dir_operations; 1483e25eb9cSAl Viro inc_nlink(inode); 1493e25eb9cSAl Viro inc_nlink(dir); 1506623ec7cSJohn Johansen } else if (S_ISLNK(mode)) { 1516623ec7cSJohn Johansen inode->i_op = iops ? iops : &simple_symlink_inode_operations; 1526623ec7cSJohn Johansen inode->i_link = data; 1533e25eb9cSAl Viro } else { 1543e25eb9cSAl Viro inode->i_fop = fops; 1553e25eb9cSAl Viro } 1563e25eb9cSAl Viro d_instantiate(dentry, inode); 1573e25eb9cSAl Viro dget(dentry); 1585955102cSAl Viro inode_unlock(dir); 1593e25eb9cSAl Viro return dentry; 1603e25eb9cSAl Viro 1613e25eb9cSAl Viro out1: 1623e25eb9cSAl Viro dput(dentry); 1633e25eb9cSAl Viro dentry = ERR_PTR(error); 1643e25eb9cSAl Viro out: 1655955102cSAl Viro inode_unlock(dir); 1663e25eb9cSAl Viro simple_release_fs(&mount, &mount_count); 167b67dbf9dSGreg KH return dentry; 168b67dbf9dSGreg KH } 1696623ec7cSJohn Johansen 1706623ec7cSJohn Johansen /** 1716623ec7cSJohn Johansen * securityfs_create_file - create a file in the securityfs filesystem 1726623ec7cSJohn Johansen * 1736623ec7cSJohn Johansen * @name: a pointer to a string containing the name of the file to create. 1746623ec7cSJohn Johansen * @mode: the permission that the file should have 1756623ec7cSJohn Johansen * @parent: a pointer to the parent dentry for this file. This should be a 1766623ec7cSJohn Johansen * directory dentry if set. If this parameter is %NULL, then the 1776623ec7cSJohn Johansen * file will be created in the root of the securityfs filesystem. 1786623ec7cSJohn Johansen * @data: a pointer to something that the caller will want to get to later 1796623ec7cSJohn Johansen * on. The inode.i_private pointer will point to this value on 1806623ec7cSJohn Johansen * the open() call. 1816623ec7cSJohn Johansen * @fops: a pointer to a struct file_operations that should be used for 1826623ec7cSJohn Johansen * this file. 1836623ec7cSJohn Johansen * 1846623ec7cSJohn Johansen * This function creates a file in securityfs with the given @name. 1856623ec7cSJohn Johansen * 1866623ec7cSJohn Johansen * This function returns a pointer to a dentry if it succeeds. This 1876623ec7cSJohn Johansen * pointer must be passed to the securityfs_remove() function when the file is 1886623ec7cSJohn Johansen * to be removed (no automatic cleanup happens if your module is unloaded, 1896623ec7cSJohn Johansen * you are responsible here). If an error occurs, the function will return 1906623ec7cSJohn Johansen * the error value (via ERR_PTR). 1916623ec7cSJohn Johansen * 1926623ec7cSJohn Johansen * If securityfs is not enabled in the kernel, the value %-ENODEV is 1936623ec7cSJohn Johansen * returned. 1946623ec7cSJohn Johansen */ 1956623ec7cSJohn Johansen struct dentry *securityfs_create_file(const char *name, umode_t mode, 1966623ec7cSJohn Johansen struct dentry *parent, void *data, 1976623ec7cSJohn Johansen const struct file_operations *fops) 1986623ec7cSJohn Johansen { 1996623ec7cSJohn Johansen return securityfs_create_dentry(name, mode, parent, data, fops, NULL); 2006623ec7cSJohn Johansen } 201b67dbf9dSGreg KH EXPORT_SYMBOL_GPL(securityfs_create_file); 202b67dbf9dSGreg KH 203b67dbf9dSGreg KH /** 204b67dbf9dSGreg KH * securityfs_create_dir - create a directory in the securityfs filesystem 205b67dbf9dSGreg KH * 206b67dbf9dSGreg KH * @name: a pointer to a string containing the name of the directory to 207b67dbf9dSGreg KH * create. 208b67dbf9dSGreg KH * @parent: a pointer to the parent dentry for this file. This should be a 2093f23d815SRandy Dunlap * directory dentry if set. If this parameter is %NULL, then the 210b67dbf9dSGreg KH * directory will be created in the root of the securityfs filesystem. 211b67dbf9dSGreg KH * 2123f23d815SRandy Dunlap * This function creates a directory in securityfs with the given @name. 213b67dbf9dSGreg KH * 2143f23d815SRandy Dunlap * This function returns a pointer to a dentry if it succeeds. This 215b67dbf9dSGreg KH * pointer must be passed to the securityfs_remove() function when the file is 216b67dbf9dSGreg KH * to be removed (no automatic cleanup happens if your module is unloaded, 2171b460651SLaurent Georget * you are responsible here). If an error occurs, the function will return 2181b460651SLaurent Georget * the error value (via ERR_PTR). 219b67dbf9dSGreg KH * 2203f23d815SRandy Dunlap * If securityfs is not enabled in the kernel, the value %-ENODEV is 2211b460651SLaurent Georget * returned. 222b67dbf9dSGreg KH */ 223b67dbf9dSGreg KH struct dentry *securityfs_create_dir(const char *name, struct dentry *parent) 224b67dbf9dSGreg KH { 2256623ec7cSJohn Johansen return securityfs_create_file(name, S_IFDIR | 0755, parent, NULL, NULL); 226b67dbf9dSGreg KH } 227b67dbf9dSGreg KH EXPORT_SYMBOL_GPL(securityfs_create_dir); 228b67dbf9dSGreg KH 229b67dbf9dSGreg KH /** 2306623ec7cSJohn Johansen * securityfs_create_symlink - create a symlink in the securityfs filesystem 2316623ec7cSJohn Johansen * 2326623ec7cSJohn Johansen * @name: a pointer to a string containing the name of the symlink to 2336623ec7cSJohn Johansen * create. 2346623ec7cSJohn Johansen * @parent: a pointer to the parent dentry for the symlink. This should be a 2356623ec7cSJohn Johansen * directory dentry if set. If this parameter is %NULL, then the 2366623ec7cSJohn Johansen * directory will be created in the root of the securityfs filesystem. 2376623ec7cSJohn Johansen * @target: a pointer to a string containing the name of the symlink's target. 2386623ec7cSJohn Johansen * If this parameter is %NULL, then the @iops parameter needs to be 2396623ec7cSJohn Johansen * setup to handle .readlink and .get_link inode_operations. 2406623ec7cSJohn Johansen * @iops: a pointer to the struct inode_operations to use for the symlink. If 2416623ec7cSJohn Johansen * this parameter is %NULL, then the default simple_symlink_inode 2426623ec7cSJohn Johansen * operations will be used. 2436623ec7cSJohn Johansen * 2446623ec7cSJohn Johansen * This function creates a symlink in securityfs with the given @name. 2456623ec7cSJohn Johansen * 2466623ec7cSJohn Johansen * This function returns a pointer to a dentry if it succeeds. This 2476623ec7cSJohn Johansen * pointer must be passed to the securityfs_remove() function when the file is 2486623ec7cSJohn Johansen * to be removed (no automatic cleanup happens if your module is unloaded, 2496623ec7cSJohn Johansen * you are responsible here). If an error occurs, the function will return 2506623ec7cSJohn Johansen * the error value (via ERR_PTR). 2516623ec7cSJohn Johansen * 2526623ec7cSJohn Johansen * If securityfs is not enabled in the kernel, the value %-ENODEV is 2536623ec7cSJohn Johansen * returned. 2546623ec7cSJohn Johansen */ 2556623ec7cSJohn Johansen struct dentry *securityfs_create_symlink(const char *name, 2566623ec7cSJohn Johansen struct dentry *parent, 2576623ec7cSJohn Johansen const char *target, 2586623ec7cSJohn Johansen const struct inode_operations *iops) 2596623ec7cSJohn Johansen { 2606623ec7cSJohn Johansen struct dentry *dent; 2616623ec7cSJohn Johansen char *link = NULL; 2626623ec7cSJohn Johansen 2636623ec7cSJohn Johansen if (target) { 2646623ec7cSJohn Johansen link = kstrdup(target, GFP_KERNEL); 2656623ec7cSJohn Johansen if (!link) 2666623ec7cSJohn Johansen return ERR_PTR(-ENOMEM); 2676623ec7cSJohn Johansen } 2686623ec7cSJohn Johansen dent = securityfs_create_dentry(name, S_IFLNK | 0444, parent, 2696623ec7cSJohn Johansen link, NULL, iops); 2706623ec7cSJohn Johansen if (IS_ERR(dent)) 2716623ec7cSJohn Johansen kfree(link); 2726623ec7cSJohn Johansen 2736623ec7cSJohn Johansen return dent; 2746623ec7cSJohn Johansen } 2756623ec7cSJohn Johansen EXPORT_SYMBOL_GPL(securityfs_create_symlink); 2766623ec7cSJohn Johansen 2776623ec7cSJohn Johansen /** 278b67dbf9dSGreg KH * securityfs_remove - removes a file or directory from the securityfs filesystem 279b67dbf9dSGreg KH * 2803f23d815SRandy Dunlap * @dentry: a pointer to a the dentry of the file or directory to be removed. 281b67dbf9dSGreg KH * 282b67dbf9dSGreg KH * This function removes a file or directory in securityfs that was previously 283b67dbf9dSGreg KH * created with a call to another securityfs function (like 284b67dbf9dSGreg KH * securityfs_create_file() or variants thereof.) 285b67dbf9dSGreg KH * 286b67dbf9dSGreg KH * This function is required to be called in order for the file to be 2873f23d815SRandy Dunlap * removed. No automatic cleanup of files will happen when a module is 2883f23d815SRandy Dunlap * removed; you are responsible here. 289b67dbf9dSGreg KH */ 290b67dbf9dSGreg KH void securityfs_remove(struct dentry *dentry) 291b67dbf9dSGreg KH { 2924093d306SAl Viro struct inode *dir; 293b67dbf9dSGreg KH 294d93e4c94SEric Paris if (!dentry || IS_ERR(dentry)) 295b67dbf9dSGreg KH return; 296b67dbf9dSGreg KH 2974093d306SAl Viro dir = d_inode(dentry->d_parent); 2984093d306SAl Viro inode_lock(dir); 299dc3f4198SAl Viro if (simple_positive(dentry)) { 300e36cb0b8SDavid Howells if (d_is_dir(dentry)) 3014093d306SAl Viro simple_rmdir(dir, dentry); 302b67dbf9dSGreg KH else 3034093d306SAl Viro simple_unlink(dir, dentry); 304b67dbf9dSGreg KH dput(dentry); 305b67dbf9dSGreg KH } 3064093d306SAl Viro inode_unlock(dir); 307b67dbf9dSGreg KH simple_release_fs(&mount, &mount_count); 308b67dbf9dSGreg KH } 309b67dbf9dSGreg KH EXPORT_SYMBOL_GPL(securityfs_remove); 310b67dbf9dSGreg KH 311d69dece5SCasey Schaufler #ifdef CONFIG_SECURITY 312d69dece5SCasey Schaufler static struct dentry *lsm_dentry; 313d69dece5SCasey Schaufler static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count, 314d69dece5SCasey Schaufler loff_t *ppos) 315d69dece5SCasey Schaufler { 316d69dece5SCasey Schaufler return simple_read_from_buffer(buf, count, ppos, lsm_names, 317d69dece5SCasey Schaufler strlen(lsm_names)); 318d69dece5SCasey Schaufler } 319d69dece5SCasey Schaufler 320d69dece5SCasey Schaufler static const struct file_operations lsm_ops = { 321d69dece5SCasey Schaufler .read = lsm_read, 322d69dece5SCasey Schaufler .llseek = generic_file_llseek, 323d69dece5SCasey Schaufler }; 324d69dece5SCasey Schaufler #endif 325d69dece5SCasey Schaufler 326b67dbf9dSGreg KH static int __init securityfs_init(void) 327b67dbf9dSGreg KH { 328b67dbf9dSGreg KH int retval; 329b67dbf9dSGreg KH 330f9bb4882SEric W. Biederman retval = sysfs_create_mount_point(kernel_kobj, "security"); 331f9bb4882SEric W. Biederman if (retval) 332f9bb4882SEric W. Biederman return retval; 333b67dbf9dSGreg KH 334b67dbf9dSGreg KH retval = register_filesystem(&fs_type); 335d69dece5SCasey Schaufler if (retval) { 336f9bb4882SEric W. Biederman sysfs_remove_mount_point(kernel_kobj, "security"); 337b67dbf9dSGreg KH return retval; 338b67dbf9dSGreg KH } 339d69dece5SCasey Schaufler #ifdef CONFIG_SECURITY 340d69dece5SCasey Schaufler lsm_dentry = securityfs_create_file("lsm", 0444, NULL, NULL, 341d69dece5SCasey Schaufler &lsm_ops); 342d69dece5SCasey Schaufler #endif 343d69dece5SCasey Schaufler return 0; 344d69dece5SCasey Schaufler } 345b67dbf9dSGreg KH core_initcall(securityfs_init); 346