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> 195c86d7e0SDavid Howells #include <linux/fs_context.h> 20b67dbf9dSGreg KH #include <linux/mount.h> 21b67dbf9dSGreg KH #include <linux/pagemap.h> 22b67dbf9dSGreg KH #include <linux/init.h> 23b67dbf9dSGreg KH #include <linux/namei.h> 24b67dbf9dSGreg KH #include <linux/security.h> 25d69dece5SCasey Schaufler #include <linux/lsm_hooks.h> 2692562927SMimi Zohar #include <linux/magic.h> 27b67dbf9dSGreg KH 28b67dbf9dSGreg KH static struct vfsmount *mount; 29b67dbf9dSGreg KH static int mount_count; 30b67dbf9dSGreg KH 31f614ee1eSAl Viro static void securityfs_free_inode(struct inode *inode) 326623ec7cSJohn Johansen { 336623ec7cSJohn Johansen if (S_ISLNK(inode->i_mode)) 346623ec7cSJohn Johansen kfree(inode->i_link); 3546c87441SAl Viro free_inode_nonrcu(inode); 3646c87441SAl Viro } 3746c87441SAl Viro 386623ec7cSJohn Johansen static const struct super_operations securityfs_super_operations = { 396623ec7cSJohn Johansen .statfs = simple_statfs, 40f614ee1eSAl Viro .free_inode = securityfs_free_inode, 416623ec7cSJohn Johansen }; 426623ec7cSJohn Johansen 435c86d7e0SDavid Howells static int securityfs_fill_super(struct super_block *sb, struct fs_context *fc) 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 575c86d7e0SDavid Howells static int securityfs_get_tree(struct fs_context *fc) 58b67dbf9dSGreg KH { 595c86d7e0SDavid Howells return get_tree_single(fc, securityfs_fill_super); 605c86d7e0SDavid Howells } 615c86d7e0SDavid Howells 625c86d7e0SDavid Howells static const struct fs_context_operations securityfs_context_ops = { 635c86d7e0SDavid Howells .get_tree = securityfs_get_tree, 645c86d7e0SDavid Howells }; 655c86d7e0SDavid Howells 665c86d7e0SDavid Howells static int securityfs_init_fs_context(struct fs_context *fc) 675c86d7e0SDavid Howells { 685c86d7e0SDavid Howells fc->ops = &securityfs_context_ops; 695c86d7e0SDavid Howells return 0; 70b67dbf9dSGreg KH } 71b67dbf9dSGreg KH 72b67dbf9dSGreg KH static struct file_system_type fs_type = { 73b67dbf9dSGreg KH .owner = THIS_MODULE, 74b67dbf9dSGreg KH .name = "securityfs", 755c86d7e0SDavid Howells .init_fs_context = securityfs_init_fs_context, 76b67dbf9dSGreg KH .kill_sb = kill_litter_super, 77b67dbf9dSGreg KH }; 78b67dbf9dSGreg KH 79b67dbf9dSGreg KH /** 806623ec7cSJohn Johansen * securityfs_create_dentry - create a dentry in the securityfs filesystem 81b67dbf9dSGreg KH * 82b67dbf9dSGreg KH * @name: a pointer to a string containing the name of the file to create. 83b67dbf9dSGreg KH * @mode: the permission that the file should have 84b67dbf9dSGreg KH * @parent: a pointer to the parent dentry for this file. This should be a 853f23d815SRandy Dunlap * directory dentry if set. If this parameter is %NULL, then the 86b67dbf9dSGreg KH * file will be created in the root of the securityfs filesystem. 87b67dbf9dSGreg KH * @data: a pointer to something that the caller will want to get to later 888e18e294STheodore Ts'o * on. The inode.i_private pointer will point to this value on 89b67dbf9dSGreg KH * the open() call. 90b67dbf9dSGreg KH * @fops: a pointer to a struct file_operations that should be used for 91b67dbf9dSGreg KH * this file. 926623ec7cSJohn Johansen * @iops: a point to a struct of inode_operations that should be used for 936623ec7cSJohn Johansen * this file/dir 94b67dbf9dSGreg KH * 956623ec7cSJohn Johansen * This is the basic "create a file/dir/symlink" function for 966623ec7cSJohn Johansen * securityfs. It allows for a wide range of flexibility in creating 976623ec7cSJohn Johansen * a file, or a directory (if you want to create a directory, the 986623ec7cSJohn Johansen * securityfs_create_dir() function is recommended to be used 996623ec7cSJohn Johansen * instead). 100b67dbf9dSGreg KH * 1013f23d815SRandy Dunlap * This function returns a pointer to a dentry if it succeeds. This 1026623ec7cSJohn Johansen * pointer must be passed to the securityfs_remove() function when the 1036623ec7cSJohn Johansen * file is to be removed (no automatic cleanup happens if your module 1046623ec7cSJohn Johansen * is unloaded, you are responsible here). If an error occurs, the 1056623ec7cSJohn Johansen * function will return the error value (via ERR_PTR). 106b67dbf9dSGreg KH * 1073f23d815SRandy Dunlap * If securityfs is not enabled in the kernel, the value %-ENODEV is 108faa3aad7SSerge E. Hallyn * returned. 109b67dbf9dSGreg KH */ 1106623ec7cSJohn Johansen static struct dentry *securityfs_create_dentry(const char *name, umode_t mode, 111b67dbf9dSGreg KH struct dentry *parent, void *data, 1126623ec7cSJohn Johansen const struct file_operations *fops, 1136623ec7cSJohn Johansen const struct inode_operations *iops) 114b67dbf9dSGreg KH { 1153e25eb9cSAl Viro struct dentry *dentry; 1163e25eb9cSAl Viro struct inode *dir, *inode; 117b67dbf9dSGreg KH int error; 118b67dbf9dSGreg KH 1196623ec7cSJohn Johansen if (!(mode & S_IFMT)) 1203e25eb9cSAl Viro mode = (mode & S_IALLUGO) | S_IFREG; 1213e25eb9cSAl Viro 122b67dbf9dSGreg KH pr_debug("securityfs: creating file '%s'\n",name); 123b67dbf9dSGreg KH 1241f5ce9e9STrond Myklebust error = simple_pin_fs(&fs_type, &mount, &mount_count); 1253e25eb9cSAl Viro if (error) 1263e25eb9cSAl Viro return ERR_PTR(error); 127b67dbf9dSGreg KH 1283e25eb9cSAl Viro if (!parent) 1293e25eb9cSAl Viro parent = mount->mnt_root; 1303e25eb9cSAl Viro 131ce0b16ddSDavid Howells dir = d_inode(parent); 1323e25eb9cSAl Viro 1335955102cSAl Viro inode_lock(dir); 1343e25eb9cSAl Viro dentry = lookup_one_len(name, parent, strlen(name)); 1353e25eb9cSAl Viro if (IS_ERR(dentry)) 1363e25eb9cSAl Viro goto out; 137b67dbf9dSGreg KH 138ce0b16ddSDavid Howells if (d_really_is_positive(dentry)) { 1393e25eb9cSAl Viro error = -EEXIST; 1403e25eb9cSAl Viro goto out1; 141b67dbf9dSGreg KH } 1423e25eb9cSAl Viro 1433e25eb9cSAl Viro inode = new_inode(dir->i_sb); 1443e25eb9cSAl Viro if (!inode) { 1453e25eb9cSAl Viro error = -ENOMEM; 1463e25eb9cSAl Viro goto out1; 1473e25eb9cSAl Viro } 1483e25eb9cSAl Viro 1493e25eb9cSAl Viro inode->i_ino = get_next_ino(); 1503e25eb9cSAl Viro inode->i_mode = mode; 151078cd827SDeepa Dinamani inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); 1523e25eb9cSAl Viro inode->i_private = data; 1536623ec7cSJohn Johansen if (S_ISDIR(mode)) { 1543e25eb9cSAl Viro inode->i_op = &simple_dir_inode_operations; 1553e25eb9cSAl Viro inode->i_fop = &simple_dir_operations; 1563e25eb9cSAl Viro inc_nlink(inode); 1573e25eb9cSAl Viro inc_nlink(dir); 1586623ec7cSJohn Johansen } else if (S_ISLNK(mode)) { 1596623ec7cSJohn Johansen inode->i_op = iops ? iops : &simple_symlink_inode_operations; 1606623ec7cSJohn Johansen inode->i_link = data; 1613e25eb9cSAl Viro } else { 1623e25eb9cSAl Viro inode->i_fop = fops; 1633e25eb9cSAl Viro } 1643e25eb9cSAl Viro d_instantiate(dentry, inode); 1653e25eb9cSAl Viro dget(dentry); 1665955102cSAl Viro inode_unlock(dir); 1673e25eb9cSAl Viro return dentry; 1683e25eb9cSAl Viro 1693e25eb9cSAl Viro out1: 1703e25eb9cSAl Viro dput(dentry); 1713e25eb9cSAl Viro dentry = ERR_PTR(error); 1723e25eb9cSAl Viro out: 1735955102cSAl Viro inode_unlock(dir); 1743e25eb9cSAl Viro simple_release_fs(&mount, &mount_count); 175b67dbf9dSGreg KH return dentry; 176b67dbf9dSGreg KH } 1776623ec7cSJohn Johansen 1786623ec7cSJohn Johansen /** 1796623ec7cSJohn Johansen * securityfs_create_file - create a file in the securityfs filesystem 1806623ec7cSJohn Johansen * 1816623ec7cSJohn Johansen * @name: a pointer to a string containing the name of the file to create. 1826623ec7cSJohn Johansen * @mode: the permission that the file should have 1836623ec7cSJohn Johansen * @parent: a pointer to the parent dentry for this file. This should be a 1846623ec7cSJohn Johansen * directory dentry if set. If this parameter is %NULL, then the 1856623ec7cSJohn Johansen * file will be created in the root of the securityfs filesystem. 1866623ec7cSJohn Johansen * @data: a pointer to something that the caller will want to get to later 1876623ec7cSJohn Johansen * on. The inode.i_private pointer will point to this value on 1886623ec7cSJohn Johansen * the open() call. 1896623ec7cSJohn Johansen * @fops: a pointer to a struct file_operations that should be used for 1906623ec7cSJohn Johansen * this file. 1916623ec7cSJohn Johansen * 1926623ec7cSJohn Johansen * This function creates a file in securityfs with the given @name. 1936623ec7cSJohn Johansen * 1946623ec7cSJohn Johansen * This function returns a pointer to a dentry if it succeeds. This 1956623ec7cSJohn Johansen * pointer must be passed to the securityfs_remove() function when the file is 1966623ec7cSJohn Johansen * to be removed (no automatic cleanup happens if your module is unloaded, 1976623ec7cSJohn Johansen * you are responsible here). If an error occurs, the function will return 1986623ec7cSJohn Johansen * the error value (via ERR_PTR). 1996623ec7cSJohn Johansen * 2006623ec7cSJohn Johansen * If securityfs is not enabled in the kernel, the value %-ENODEV is 2016623ec7cSJohn Johansen * returned. 2026623ec7cSJohn Johansen */ 2036623ec7cSJohn Johansen struct dentry *securityfs_create_file(const char *name, umode_t mode, 2046623ec7cSJohn Johansen struct dentry *parent, void *data, 2056623ec7cSJohn Johansen const struct file_operations *fops) 2066623ec7cSJohn Johansen { 2076623ec7cSJohn Johansen return securityfs_create_dentry(name, mode, parent, data, fops, NULL); 2086623ec7cSJohn Johansen } 209b67dbf9dSGreg KH EXPORT_SYMBOL_GPL(securityfs_create_file); 210b67dbf9dSGreg KH 211b67dbf9dSGreg KH /** 212b67dbf9dSGreg KH * securityfs_create_dir - create a directory in the securityfs filesystem 213b67dbf9dSGreg KH * 214b67dbf9dSGreg KH * @name: a pointer to a string containing the name of the directory to 215b67dbf9dSGreg KH * create. 216b67dbf9dSGreg KH * @parent: a pointer to the parent dentry for this file. This should be a 2173f23d815SRandy Dunlap * directory dentry if set. If this parameter is %NULL, then the 218b67dbf9dSGreg KH * directory will be created in the root of the securityfs filesystem. 219b67dbf9dSGreg KH * 2203f23d815SRandy Dunlap * This function creates a directory in securityfs with the given @name. 221b67dbf9dSGreg KH * 2223f23d815SRandy Dunlap * This function returns a pointer to a dentry if it succeeds. This 223b67dbf9dSGreg KH * pointer must be passed to the securityfs_remove() function when the file is 224b67dbf9dSGreg KH * to be removed (no automatic cleanup happens if your module is unloaded, 2251b460651SLaurent Georget * you are responsible here). If an error occurs, the function will return 2261b460651SLaurent Georget * the error value (via ERR_PTR). 227b67dbf9dSGreg KH * 2283f23d815SRandy Dunlap * If securityfs is not enabled in the kernel, the value %-ENODEV is 2291b460651SLaurent Georget * returned. 230b67dbf9dSGreg KH */ 231b67dbf9dSGreg KH struct dentry *securityfs_create_dir(const char *name, struct dentry *parent) 232b67dbf9dSGreg KH { 2336623ec7cSJohn Johansen return securityfs_create_file(name, S_IFDIR | 0755, parent, NULL, NULL); 234b67dbf9dSGreg KH } 235b67dbf9dSGreg KH EXPORT_SYMBOL_GPL(securityfs_create_dir); 236b67dbf9dSGreg KH 237b67dbf9dSGreg KH /** 2386623ec7cSJohn Johansen * securityfs_create_symlink - create a symlink in the securityfs filesystem 2396623ec7cSJohn Johansen * 2406623ec7cSJohn Johansen * @name: a pointer to a string containing the name of the symlink to 2416623ec7cSJohn Johansen * create. 2426623ec7cSJohn Johansen * @parent: a pointer to the parent dentry for the symlink. This should be a 2436623ec7cSJohn Johansen * directory dentry if set. If this parameter is %NULL, then the 2446623ec7cSJohn Johansen * directory will be created in the root of the securityfs filesystem. 2456623ec7cSJohn Johansen * @target: a pointer to a string containing the name of the symlink's target. 2466623ec7cSJohn Johansen * If this parameter is %NULL, then the @iops parameter needs to be 2476623ec7cSJohn Johansen * setup to handle .readlink and .get_link inode_operations. 2486623ec7cSJohn Johansen * @iops: a pointer to the struct inode_operations to use for the symlink. If 2496623ec7cSJohn Johansen * this parameter is %NULL, then the default simple_symlink_inode 2506623ec7cSJohn Johansen * operations will be used. 2516623ec7cSJohn Johansen * 2526623ec7cSJohn Johansen * This function creates a symlink in securityfs with the given @name. 2536623ec7cSJohn Johansen * 2546623ec7cSJohn Johansen * This function returns a pointer to a dentry if it succeeds. This 2556623ec7cSJohn Johansen * pointer must be passed to the securityfs_remove() function when the file is 2566623ec7cSJohn Johansen * to be removed (no automatic cleanup happens if your module is unloaded, 2576623ec7cSJohn Johansen * you are responsible here). If an error occurs, the function will return 2586623ec7cSJohn Johansen * the error value (via ERR_PTR). 2596623ec7cSJohn Johansen * 2606623ec7cSJohn Johansen * If securityfs is not enabled in the kernel, the value %-ENODEV is 2616623ec7cSJohn Johansen * returned. 2626623ec7cSJohn Johansen */ 2636623ec7cSJohn Johansen struct dentry *securityfs_create_symlink(const char *name, 2646623ec7cSJohn Johansen struct dentry *parent, 2656623ec7cSJohn Johansen const char *target, 2666623ec7cSJohn Johansen const struct inode_operations *iops) 2676623ec7cSJohn Johansen { 2686623ec7cSJohn Johansen struct dentry *dent; 2696623ec7cSJohn Johansen char *link = NULL; 2706623ec7cSJohn Johansen 2716623ec7cSJohn Johansen if (target) { 2726623ec7cSJohn Johansen link = kstrdup(target, GFP_KERNEL); 2736623ec7cSJohn Johansen if (!link) 2746623ec7cSJohn Johansen return ERR_PTR(-ENOMEM); 2756623ec7cSJohn Johansen } 2766623ec7cSJohn Johansen dent = securityfs_create_dentry(name, S_IFLNK | 0444, parent, 2776623ec7cSJohn Johansen link, NULL, iops); 2786623ec7cSJohn Johansen if (IS_ERR(dent)) 2796623ec7cSJohn Johansen kfree(link); 2806623ec7cSJohn Johansen 2816623ec7cSJohn Johansen return dent; 2826623ec7cSJohn Johansen } 2836623ec7cSJohn Johansen EXPORT_SYMBOL_GPL(securityfs_create_symlink); 2846623ec7cSJohn Johansen 2856623ec7cSJohn Johansen /** 286b67dbf9dSGreg KH * securityfs_remove - removes a file or directory from the securityfs filesystem 287b67dbf9dSGreg KH * 2883f23d815SRandy Dunlap * @dentry: a pointer to a the dentry of the file or directory to be removed. 289b67dbf9dSGreg KH * 290b67dbf9dSGreg KH * This function removes a file or directory in securityfs that was previously 291b67dbf9dSGreg KH * created with a call to another securityfs function (like 292b67dbf9dSGreg KH * securityfs_create_file() or variants thereof.) 293b67dbf9dSGreg KH * 294b67dbf9dSGreg KH * This function is required to be called in order for the file to be 2953f23d815SRandy Dunlap * removed. No automatic cleanup of files will happen when a module is 2963f23d815SRandy Dunlap * removed; you are responsible here. 297b67dbf9dSGreg KH */ 298b67dbf9dSGreg KH void securityfs_remove(struct dentry *dentry) 299b67dbf9dSGreg KH { 3004093d306SAl Viro struct inode *dir; 301b67dbf9dSGreg KH 302d93e4c94SEric Paris if (!dentry || IS_ERR(dentry)) 303b67dbf9dSGreg KH return; 304b67dbf9dSGreg KH 3054093d306SAl Viro dir = d_inode(dentry->d_parent); 3064093d306SAl Viro inode_lock(dir); 307dc3f4198SAl Viro if (simple_positive(dentry)) { 308e36cb0b8SDavid Howells if (d_is_dir(dentry)) 3094093d306SAl Viro simple_rmdir(dir, dentry); 310b67dbf9dSGreg KH else 3114093d306SAl Viro simple_unlink(dir, dentry); 312b67dbf9dSGreg KH dput(dentry); 313b67dbf9dSGreg KH } 3144093d306SAl Viro inode_unlock(dir); 315b67dbf9dSGreg KH simple_release_fs(&mount, &mount_count); 316b67dbf9dSGreg KH } 317b67dbf9dSGreg KH EXPORT_SYMBOL_GPL(securityfs_remove); 318b67dbf9dSGreg KH 319d69dece5SCasey Schaufler #ifdef CONFIG_SECURITY 320d69dece5SCasey Schaufler static struct dentry *lsm_dentry; 321d69dece5SCasey Schaufler static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count, 322d69dece5SCasey Schaufler loff_t *ppos) 323d69dece5SCasey Schaufler { 324d69dece5SCasey Schaufler return simple_read_from_buffer(buf, count, ppos, lsm_names, 325d69dece5SCasey Schaufler strlen(lsm_names)); 326d69dece5SCasey Schaufler } 327d69dece5SCasey Schaufler 328d69dece5SCasey Schaufler static const struct file_operations lsm_ops = { 329d69dece5SCasey Schaufler .read = lsm_read, 330d69dece5SCasey Schaufler .llseek = generic_file_llseek, 331d69dece5SCasey Schaufler }; 332d69dece5SCasey Schaufler #endif 333d69dece5SCasey Schaufler 334b67dbf9dSGreg KH static int __init securityfs_init(void) 335b67dbf9dSGreg KH { 336b67dbf9dSGreg KH int retval; 337b67dbf9dSGreg KH 338f9bb4882SEric W. Biederman retval = sysfs_create_mount_point(kernel_kobj, "security"); 339f9bb4882SEric W. Biederman if (retval) 340f9bb4882SEric W. Biederman return retval; 341b67dbf9dSGreg KH 342b67dbf9dSGreg KH retval = register_filesystem(&fs_type); 343d69dece5SCasey Schaufler if (retval) { 344f9bb4882SEric W. Biederman sysfs_remove_mount_point(kernel_kobj, "security"); 345b67dbf9dSGreg KH return retval; 346b67dbf9dSGreg KH } 347d69dece5SCasey Schaufler #ifdef CONFIG_SECURITY 348d69dece5SCasey Schaufler lsm_dentry = securityfs_create_file("lsm", 0444, NULL, NULL, 349d69dece5SCasey Schaufler &lsm_ops); 350d69dece5SCasey Schaufler #endif 351d69dece5SCasey Schaufler return 0; 352d69dece5SCasey Schaufler } 353b67dbf9dSGreg KH core_initcall(securityfs_init); 354