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 */ 16b67dbf9dSGreg KH #include <linux/module.h> 17b67dbf9dSGreg KH #include <linux/fs.h> 18b67dbf9dSGreg KH #include <linux/mount.h> 19b67dbf9dSGreg KH #include <linux/pagemap.h> 20b67dbf9dSGreg KH #include <linux/init.h> 21b67dbf9dSGreg KH #include <linux/namei.h> 22b67dbf9dSGreg KH #include <linux/security.h> 23d69dece5SCasey Schaufler #include <linux/lsm_hooks.h> 2492562927SMimi Zohar #include <linux/magic.h> 25b67dbf9dSGreg KH 26b67dbf9dSGreg KH static struct vfsmount *mount; 27b67dbf9dSGreg KH static int mount_count; 28b67dbf9dSGreg KH 29b67dbf9dSGreg KH static int fill_super(struct super_block *sb, void *data, int silent) 30b67dbf9dSGreg KH { 31b67dbf9dSGreg KH static struct tree_descr files[] = {{""}}; 32b67dbf9dSGreg KH 33b67dbf9dSGreg KH return simple_fill_super(sb, SECURITYFS_MAGIC, files); 34b67dbf9dSGreg KH } 35b67dbf9dSGreg KH 36fc14f2feSAl Viro static struct dentry *get_sb(struct file_system_type *fs_type, 37b67dbf9dSGreg KH int flags, const char *dev_name, 38fc14f2feSAl Viro void *data) 39b67dbf9dSGreg KH { 40fc14f2feSAl Viro return mount_single(fs_type, flags, data, fill_super); 41b67dbf9dSGreg KH } 42b67dbf9dSGreg KH 43b67dbf9dSGreg KH static struct file_system_type fs_type = { 44b67dbf9dSGreg KH .owner = THIS_MODULE, 45b67dbf9dSGreg KH .name = "securityfs", 46fc14f2feSAl Viro .mount = get_sb, 47b67dbf9dSGreg KH .kill_sb = kill_litter_super, 48b67dbf9dSGreg KH }; 49b67dbf9dSGreg KH 50b67dbf9dSGreg KH /** 51b67dbf9dSGreg KH * securityfs_create_file - create a file in the securityfs filesystem 52b67dbf9dSGreg KH * 53b67dbf9dSGreg KH * @name: a pointer to a string containing the name of the file to create. 54b67dbf9dSGreg KH * @mode: the permission that the file should have 55b67dbf9dSGreg KH * @parent: a pointer to the parent dentry for this file. This should be a 563f23d815SRandy Dunlap * directory dentry if set. If this parameter is %NULL, then the 57b67dbf9dSGreg KH * file will be created in the root of the securityfs filesystem. 58b67dbf9dSGreg KH * @data: a pointer to something that the caller will want to get to later 598e18e294STheodore Ts'o * on. The inode.i_private pointer will point to this value on 60b67dbf9dSGreg KH * the open() call. 61b67dbf9dSGreg KH * @fops: a pointer to a struct file_operations that should be used for 62b67dbf9dSGreg KH * this file. 63b67dbf9dSGreg KH * 64b67dbf9dSGreg KH * This is the basic "create a file" function for securityfs. It allows for a 653f23d815SRandy Dunlap * wide range of flexibility in creating a file, or a directory (if you 66b67dbf9dSGreg KH * want to create a directory, the securityfs_create_dir() function is 673f23d815SRandy Dunlap * recommended to be used instead). 68b67dbf9dSGreg KH * 693f23d815SRandy Dunlap * This function returns a pointer to a dentry if it succeeds. This 70b67dbf9dSGreg KH * pointer must be passed to the securityfs_remove() function when the file is 71b67dbf9dSGreg KH * to be removed (no automatic cleanup happens if your module is unloaded, 72faa3aad7SSerge E. Hallyn * you are responsible here). If an error occurs, the function will return 73da3dae54SMasanari Iida * the error value (via ERR_PTR). 74b67dbf9dSGreg KH * 753f23d815SRandy Dunlap * If securityfs is not enabled in the kernel, the value %-ENODEV is 76faa3aad7SSerge E. Hallyn * returned. 77b67dbf9dSGreg KH */ 7852ef0c04SAl Viro struct dentry *securityfs_create_file(const char *name, umode_t mode, 79b67dbf9dSGreg KH struct dentry *parent, void *data, 809c2e08c5SArjan van de Ven const struct file_operations *fops) 81b67dbf9dSGreg KH { 823e25eb9cSAl Viro struct dentry *dentry; 833e25eb9cSAl Viro int is_dir = S_ISDIR(mode); 843e25eb9cSAl Viro struct inode *dir, *inode; 85b67dbf9dSGreg KH int error; 86b67dbf9dSGreg KH 873e25eb9cSAl Viro if (!is_dir) { 883e25eb9cSAl Viro BUG_ON(!fops); 893e25eb9cSAl Viro mode = (mode & S_IALLUGO) | S_IFREG; 903e25eb9cSAl Viro } 913e25eb9cSAl Viro 92b67dbf9dSGreg KH pr_debug("securityfs: creating file '%s'\n",name); 93b67dbf9dSGreg KH 941f5ce9e9STrond Myklebust error = simple_pin_fs(&fs_type, &mount, &mount_count); 953e25eb9cSAl Viro if (error) 963e25eb9cSAl Viro return ERR_PTR(error); 97b67dbf9dSGreg KH 983e25eb9cSAl Viro if (!parent) 993e25eb9cSAl Viro parent = mount->mnt_root; 1003e25eb9cSAl Viro 101ce0b16ddSDavid Howells dir = d_inode(parent); 1023e25eb9cSAl Viro 1035955102cSAl Viro inode_lock(dir); 1043e25eb9cSAl Viro dentry = lookup_one_len(name, parent, strlen(name)); 1053e25eb9cSAl Viro if (IS_ERR(dentry)) 1063e25eb9cSAl Viro goto out; 107b67dbf9dSGreg KH 108ce0b16ddSDavid Howells if (d_really_is_positive(dentry)) { 1093e25eb9cSAl Viro error = -EEXIST; 1103e25eb9cSAl Viro goto out1; 111b67dbf9dSGreg KH } 1123e25eb9cSAl Viro 1133e25eb9cSAl Viro inode = new_inode(dir->i_sb); 1143e25eb9cSAl Viro if (!inode) { 1153e25eb9cSAl Viro error = -ENOMEM; 1163e25eb9cSAl Viro goto out1; 1173e25eb9cSAl Viro } 1183e25eb9cSAl Viro 1193e25eb9cSAl Viro inode->i_ino = get_next_ino(); 1203e25eb9cSAl Viro inode->i_mode = mode; 121078cd827SDeepa Dinamani inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); 1223e25eb9cSAl Viro inode->i_private = data; 1233e25eb9cSAl Viro if (is_dir) { 1243e25eb9cSAl Viro inode->i_op = &simple_dir_inode_operations; 1253e25eb9cSAl Viro inode->i_fop = &simple_dir_operations; 1263e25eb9cSAl Viro inc_nlink(inode); 1273e25eb9cSAl Viro inc_nlink(dir); 1283e25eb9cSAl Viro } else { 1293e25eb9cSAl Viro inode->i_fop = fops; 1303e25eb9cSAl Viro } 1313e25eb9cSAl Viro d_instantiate(dentry, inode); 1323e25eb9cSAl Viro dget(dentry); 1335955102cSAl Viro inode_unlock(dir); 1343e25eb9cSAl Viro return dentry; 1353e25eb9cSAl Viro 1363e25eb9cSAl Viro out1: 1373e25eb9cSAl Viro dput(dentry); 1383e25eb9cSAl Viro dentry = ERR_PTR(error); 1393e25eb9cSAl Viro out: 1405955102cSAl Viro inode_unlock(dir); 1413e25eb9cSAl Viro simple_release_fs(&mount, &mount_count); 142b67dbf9dSGreg KH return dentry; 143b67dbf9dSGreg KH } 144b67dbf9dSGreg KH EXPORT_SYMBOL_GPL(securityfs_create_file); 145b67dbf9dSGreg KH 146b67dbf9dSGreg KH /** 147b67dbf9dSGreg KH * securityfs_create_dir - create a directory in the securityfs filesystem 148b67dbf9dSGreg KH * 149b67dbf9dSGreg KH * @name: a pointer to a string containing the name of the directory to 150b67dbf9dSGreg KH * create. 151b67dbf9dSGreg KH * @parent: a pointer to the parent dentry for this file. This should be a 1523f23d815SRandy Dunlap * directory dentry if set. If this parameter is %NULL, then the 153b67dbf9dSGreg KH * directory will be created in the root of the securityfs filesystem. 154b67dbf9dSGreg KH * 1553f23d815SRandy Dunlap * This function creates a directory in securityfs with the given @name. 156b67dbf9dSGreg KH * 1573f23d815SRandy Dunlap * This function returns a pointer to a dentry if it succeeds. This 158b67dbf9dSGreg KH * pointer must be passed to the securityfs_remove() function when the file is 159b67dbf9dSGreg KH * to be removed (no automatic cleanup happens if your module is unloaded, 1601b460651SLaurent Georget * you are responsible here). If an error occurs, the function will return 1611b460651SLaurent Georget * the error value (via ERR_PTR). 162b67dbf9dSGreg KH * 1633f23d815SRandy Dunlap * If securityfs is not enabled in the kernel, the value %-ENODEV is 1641b460651SLaurent Georget * returned. 165b67dbf9dSGreg KH */ 166b67dbf9dSGreg KH struct dentry *securityfs_create_dir(const char *name, struct dentry *parent) 167b67dbf9dSGreg KH { 168b67dbf9dSGreg KH return securityfs_create_file(name, 169b67dbf9dSGreg KH S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, 170b67dbf9dSGreg KH parent, NULL, NULL); 171b67dbf9dSGreg KH } 172b67dbf9dSGreg KH EXPORT_SYMBOL_GPL(securityfs_create_dir); 173b67dbf9dSGreg KH 174b67dbf9dSGreg KH /** 175b67dbf9dSGreg KH * securityfs_remove - removes a file or directory from the securityfs filesystem 176b67dbf9dSGreg KH * 1773f23d815SRandy Dunlap * @dentry: a pointer to a the dentry of the file or directory to be removed. 178b67dbf9dSGreg KH * 179b67dbf9dSGreg KH * This function removes a file or directory in securityfs that was previously 180b67dbf9dSGreg KH * created with a call to another securityfs function (like 181b67dbf9dSGreg KH * securityfs_create_file() or variants thereof.) 182b67dbf9dSGreg KH * 183b67dbf9dSGreg KH * This function is required to be called in order for the file to be 1843f23d815SRandy Dunlap * removed. No automatic cleanup of files will happen when a module is 1853f23d815SRandy Dunlap * removed; you are responsible here. 186b67dbf9dSGreg KH */ 187b67dbf9dSGreg KH void securityfs_remove(struct dentry *dentry) 188b67dbf9dSGreg KH { 1894093d306SAl Viro struct inode *dir; 190b67dbf9dSGreg KH 191d93e4c94SEric Paris if (!dentry || IS_ERR(dentry)) 192b67dbf9dSGreg KH return; 193b67dbf9dSGreg KH 1944093d306SAl Viro dir = d_inode(dentry->d_parent); 1954093d306SAl Viro inode_lock(dir); 196dc3f4198SAl Viro if (simple_positive(dentry)) { 197e36cb0b8SDavid Howells if (d_is_dir(dentry)) 1984093d306SAl Viro simple_rmdir(dir, dentry); 199b67dbf9dSGreg KH else 2004093d306SAl Viro simple_unlink(dir, dentry); 201b67dbf9dSGreg KH dput(dentry); 202b67dbf9dSGreg KH } 2034093d306SAl Viro inode_unlock(dir); 204b67dbf9dSGreg KH simple_release_fs(&mount, &mount_count); 205b67dbf9dSGreg KH } 206b67dbf9dSGreg KH EXPORT_SYMBOL_GPL(securityfs_remove); 207b67dbf9dSGreg KH 208d69dece5SCasey Schaufler #ifdef CONFIG_SECURITY 209d69dece5SCasey Schaufler static struct dentry *lsm_dentry; 210d69dece5SCasey Schaufler static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count, 211d69dece5SCasey Schaufler loff_t *ppos) 212d69dece5SCasey Schaufler { 213d69dece5SCasey Schaufler return simple_read_from_buffer(buf, count, ppos, lsm_names, 214d69dece5SCasey Schaufler strlen(lsm_names)); 215d69dece5SCasey Schaufler } 216d69dece5SCasey Schaufler 217d69dece5SCasey Schaufler static const struct file_operations lsm_ops = { 218d69dece5SCasey Schaufler .read = lsm_read, 219d69dece5SCasey Schaufler .llseek = generic_file_llseek, 220d69dece5SCasey Schaufler }; 221d69dece5SCasey Schaufler #endif 222d69dece5SCasey Schaufler 223b67dbf9dSGreg KH static int __init securityfs_init(void) 224b67dbf9dSGreg KH { 225b67dbf9dSGreg KH int retval; 226b67dbf9dSGreg KH 227f9bb4882SEric W. Biederman retval = sysfs_create_mount_point(kernel_kobj, "security"); 228f9bb4882SEric W. Biederman if (retval) 229f9bb4882SEric W. Biederman return retval; 230b67dbf9dSGreg KH 231b67dbf9dSGreg KH retval = register_filesystem(&fs_type); 232d69dece5SCasey Schaufler if (retval) { 233f9bb4882SEric W. Biederman sysfs_remove_mount_point(kernel_kobj, "security"); 234b67dbf9dSGreg KH return retval; 235b67dbf9dSGreg KH } 236d69dece5SCasey Schaufler #ifdef CONFIG_SECURITY 237d69dece5SCasey Schaufler lsm_dentry = securityfs_create_file("lsm", 0444, NULL, NULL, 238d69dece5SCasey Schaufler &lsm_ops); 239d69dece5SCasey Schaufler #endif 240d69dece5SCasey Schaufler return 0; 241d69dece5SCasey Schaufler } 242b67dbf9dSGreg KH 243b67dbf9dSGreg KH core_initcall(securityfs_init); 244b67dbf9dSGreg KH MODULE_LICENSE("GPL"); 245b67dbf9dSGreg KH 246