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> 2392562927SMimi Zohar #include <linux/magic.h> 24b67dbf9dSGreg KH 25b67dbf9dSGreg KH static struct vfsmount *mount; 26b67dbf9dSGreg KH static int mount_count; 27b67dbf9dSGreg KH 28b67dbf9dSGreg KH static inline int positive(struct dentry *dentry) 29b67dbf9dSGreg KH { 30b67dbf9dSGreg KH return dentry->d_inode && !d_unhashed(dentry); 31b67dbf9dSGreg KH } 32b67dbf9dSGreg KH 33b67dbf9dSGreg KH static int fill_super(struct super_block *sb, void *data, int silent) 34b67dbf9dSGreg KH { 35b67dbf9dSGreg KH static struct tree_descr files[] = {{""}}; 36b67dbf9dSGreg KH 37b67dbf9dSGreg KH return simple_fill_super(sb, SECURITYFS_MAGIC, files); 38b67dbf9dSGreg KH } 39b67dbf9dSGreg KH 40fc14f2feSAl Viro static struct dentry *get_sb(struct file_system_type *fs_type, 41b67dbf9dSGreg KH int flags, const char *dev_name, 42fc14f2feSAl Viro void *data) 43b67dbf9dSGreg KH { 44fc14f2feSAl Viro return mount_single(fs_type, flags, data, fill_super); 45b67dbf9dSGreg KH } 46b67dbf9dSGreg KH 47b67dbf9dSGreg KH static struct file_system_type fs_type = { 48b67dbf9dSGreg KH .owner = THIS_MODULE, 49b67dbf9dSGreg KH .name = "securityfs", 50fc14f2feSAl Viro .mount = get_sb, 51b67dbf9dSGreg KH .kill_sb = kill_litter_super, 52b67dbf9dSGreg KH }; 53b67dbf9dSGreg KH 54b67dbf9dSGreg KH /** 55b67dbf9dSGreg KH * securityfs_create_file - create a file in the securityfs filesystem 56b67dbf9dSGreg KH * 57b67dbf9dSGreg KH * @name: a pointer to a string containing the name of the file to create. 58b67dbf9dSGreg KH * @mode: the permission that the file should have 59b67dbf9dSGreg KH * @parent: a pointer to the parent dentry for this file. This should be a 603f23d815SRandy Dunlap * directory dentry if set. If this parameter is %NULL, then the 61b67dbf9dSGreg KH * file will be created in the root of the securityfs filesystem. 62b67dbf9dSGreg KH * @data: a pointer to something that the caller will want to get to later 638e18e294STheodore Ts'o * on. The inode.i_private pointer will point to this value on 64b67dbf9dSGreg KH * the open() call. 65b67dbf9dSGreg KH * @fops: a pointer to a struct file_operations that should be used for 66b67dbf9dSGreg KH * this file. 67b67dbf9dSGreg KH * 68b67dbf9dSGreg KH * This is the basic "create a file" function for securityfs. It allows for a 693f23d815SRandy Dunlap * wide range of flexibility in creating a file, or a directory (if you 70b67dbf9dSGreg KH * want to create a directory, the securityfs_create_dir() function is 713f23d815SRandy Dunlap * recommended to be used instead). 72b67dbf9dSGreg KH * 733f23d815SRandy Dunlap * This function returns a pointer to a dentry if it succeeds. This 74b67dbf9dSGreg KH * pointer must be passed to the securityfs_remove() function when the file is 75b67dbf9dSGreg KH * to be removed (no automatic cleanup happens if your module is unloaded, 76faa3aad7SSerge E. Hallyn * you are responsible here). If an error occurs, the function will return 77*da3dae54SMasanari Iida * the error value (via ERR_PTR). 78b67dbf9dSGreg KH * 793f23d815SRandy Dunlap * If securityfs is not enabled in the kernel, the value %-ENODEV is 80faa3aad7SSerge E. Hallyn * returned. 81b67dbf9dSGreg KH */ 8252ef0c04SAl Viro struct dentry *securityfs_create_file(const char *name, umode_t mode, 83b67dbf9dSGreg KH struct dentry *parent, void *data, 849c2e08c5SArjan van de Ven const struct file_operations *fops) 85b67dbf9dSGreg KH { 863e25eb9cSAl Viro struct dentry *dentry; 873e25eb9cSAl Viro int is_dir = S_ISDIR(mode); 883e25eb9cSAl Viro struct inode *dir, *inode; 89b67dbf9dSGreg KH int error; 90b67dbf9dSGreg KH 913e25eb9cSAl Viro if (!is_dir) { 923e25eb9cSAl Viro BUG_ON(!fops); 933e25eb9cSAl Viro mode = (mode & S_IALLUGO) | S_IFREG; 943e25eb9cSAl Viro } 953e25eb9cSAl Viro 96b67dbf9dSGreg KH pr_debug("securityfs: creating file '%s'\n",name); 97b67dbf9dSGreg KH 981f5ce9e9STrond Myklebust error = simple_pin_fs(&fs_type, &mount, &mount_count); 993e25eb9cSAl Viro if (error) 1003e25eb9cSAl Viro return ERR_PTR(error); 101b67dbf9dSGreg KH 1023e25eb9cSAl Viro if (!parent) 1033e25eb9cSAl Viro parent = mount->mnt_root; 1043e25eb9cSAl Viro 1053e25eb9cSAl Viro dir = parent->d_inode; 1063e25eb9cSAl Viro 1073e25eb9cSAl Viro mutex_lock(&dir->i_mutex); 1083e25eb9cSAl Viro dentry = lookup_one_len(name, parent, strlen(name)); 1093e25eb9cSAl Viro if (IS_ERR(dentry)) 1103e25eb9cSAl Viro goto out; 111b67dbf9dSGreg KH 112b67dbf9dSGreg KH if (dentry->d_inode) { 1133e25eb9cSAl Viro error = -EEXIST; 1143e25eb9cSAl Viro goto out1; 115b67dbf9dSGreg KH } 1163e25eb9cSAl Viro 1173e25eb9cSAl Viro inode = new_inode(dir->i_sb); 1183e25eb9cSAl Viro if (!inode) { 1193e25eb9cSAl Viro error = -ENOMEM; 1203e25eb9cSAl Viro goto out1; 1213e25eb9cSAl Viro } 1223e25eb9cSAl Viro 1233e25eb9cSAl Viro inode->i_ino = get_next_ino(); 1243e25eb9cSAl Viro inode->i_mode = mode; 1253e25eb9cSAl Viro inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 1263e25eb9cSAl Viro inode->i_private = data; 1273e25eb9cSAl Viro if (is_dir) { 1283e25eb9cSAl Viro inode->i_op = &simple_dir_inode_operations; 1293e25eb9cSAl Viro inode->i_fop = &simple_dir_operations; 1303e25eb9cSAl Viro inc_nlink(inode); 1313e25eb9cSAl Viro inc_nlink(dir); 1323e25eb9cSAl Viro } else { 1333e25eb9cSAl Viro inode->i_fop = fops; 1343e25eb9cSAl Viro } 1353e25eb9cSAl Viro d_instantiate(dentry, inode); 1363e25eb9cSAl Viro dget(dentry); 1373e25eb9cSAl Viro mutex_unlock(&dir->i_mutex); 1383e25eb9cSAl Viro return dentry; 1393e25eb9cSAl Viro 1403e25eb9cSAl Viro out1: 1413e25eb9cSAl Viro dput(dentry); 1423e25eb9cSAl Viro dentry = ERR_PTR(error); 1433e25eb9cSAl Viro out: 1443e25eb9cSAl Viro mutex_unlock(&dir->i_mutex); 1453e25eb9cSAl Viro simple_release_fs(&mount, &mount_count); 146b67dbf9dSGreg KH return dentry; 147b67dbf9dSGreg KH } 148b67dbf9dSGreg KH EXPORT_SYMBOL_GPL(securityfs_create_file); 149b67dbf9dSGreg KH 150b67dbf9dSGreg KH /** 151b67dbf9dSGreg KH * securityfs_create_dir - create a directory in the securityfs filesystem 152b67dbf9dSGreg KH * 153b67dbf9dSGreg KH * @name: a pointer to a string containing the name of the directory to 154b67dbf9dSGreg KH * create. 155b67dbf9dSGreg KH * @parent: a pointer to the parent dentry for this file. This should be a 1563f23d815SRandy Dunlap * directory dentry if set. If this parameter is %NULL, then the 157b67dbf9dSGreg KH * directory will be created in the root of the securityfs filesystem. 158b67dbf9dSGreg KH * 1593f23d815SRandy Dunlap * This function creates a directory in securityfs with the given @name. 160b67dbf9dSGreg KH * 1613f23d815SRandy Dunlap * This function returns a pointer to a dentry if it succeeds. This 162b67dbf9dSGreg KH * pointer must be passed to the securityfs_remove() function when the file is 163b67dbf9dSGreg KH * to be removed (no automatic cleanup happens if your module is unloaded, 1643f23d815SRandy Dunlap * you are responsible here). If an error occurs, %NULL will be returned. 165b67dbf9dSGreg KH * 1663f23d815SRandy Dunlap * If securityfs is not enabled in the kernel, the value %-ENODEV is 167b67dbf9dSGreg KH * returned. It is not wise to check for this value, but rather, check for 1683f23d815SRandy Dunlap * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling 169b67dbf9dSGreg KH * code. 170b67dbf9dSGreg KH */ 171b67dbf9dSGreg KH struct dentry *securityfs_create_dir(const char *name, struct dentry *parent) 172b67dbf9dSGreg KH { 173b67dbf9dSGreg KH return securityfs_create_file(name, 174b67dbf9dSGreg KH S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, 175b67dbf9dSGreg KH parent, NULL, NULL); 176b67dbf9dSGreg KH } 177b67dbf9dSGreg KH EXPORT_SYMBOL_GPL(securityfs_create_dir); 178b67dbf9dSGreg KH 179b67dbf9dSGreg KH /** 180b67dbf9dSGreg KH * securityfs_remove - removes a file or directory from the securityfs filesystem 181b67dbf9dSGreg KH * 1823f23d815SRandy Dunlap * @dentry: a pointer to a the dentry of the file or directory to be removed. 183b67dbf9dSGreg KH * 184b67dbf9dSGreg KH * This function removes a file or directory in securityfs that was previously 185b67dbf9dSGreg KH * created with a call to another securityfs function (like 186b67dbf9dSGreg KH * securityfs_create_file() or variants thereof.) 187b67dbf9dSGreg KH * 188b67dbf9dSGreg KH * This function is required to be called in order for the file to be 1893f23d815SRandy Dunlap * removed. No automatic cleanup of files will happen when a module is 1903f23d815SRandy Dunlap * removed; you are responsible here. 191b67dbf9dSGreg KH */ 192b67dbf9dSGreg KH void securityfs_remove(struct dentry *dentry) 193b67dbf9dSGreg KH { 194b67dbf9dSGreg KH struct dentry *parent; 195b67dbf9dSGreg KH 196d93e4c94SEric Paris if (!dentry || IS_ERR(dentry)) 197b67dbf9dSGreg KH return; 198b67dbf9dSGreg KH 199b67dbf9dSGreg KH parent = dentry->d_parent; 200b67dbf9dSGreg KH if (!parent || !parent->d_inode) 201b67dbf9dSGreg KH return; 202b67dbf9dSGreg KH 2031b1dcc1bSJes Sorensen mutex_lock(&parent->d_inode->i_mutex); 204b67dbf9dSGreg KH if (positive(dentry)) { 205b67dbf9dSGreg KH if (dentry->d_inode) { 206b67dbf9dSGreg KH if (S_ISDIR(dentry->d_inode->i_mode)) 207b67dbf9dSGreg KH simple_rmdir(parent->d_inode, dentry); 208b67dbf9dSGreg KH else 209b67dbf9dSGreg KH simple_unlink(parent->d_inode, dentry); 210b67dbf9dSGreg KH dput(dentry); 211b67dbf9dSGreg KH } 212b67dbf9dSGreg KH } 2131b1dcc1bSJes Sorensen mutex_unlock(&parent->d_inode->i_mutex); 214b67dbf9dSGreg KH simple_release_fs(&mount, &mount_count); 215b67dbf9dSGreg KH } 216b67dbf9dSGreg KH EXPORT_SYMBOL_GPL(securityfs_remove); 217b67dbf9dSGreg KH 21869d8e138SGreg Kroah-Hartman static struct kobject *security_kobj; 219b67dbf9dSGreg KH 220b67dbf9dSGreg KH static int __init securityfs_init(void) 221b67dbf9dSGreg KH { 222b67dbf9dSGreg KH int retval; 223b67dbf9dSGreg KH 2240ff21e46SGreg Kroah-Hartman security_kobj = kobject_create_and_add("security", kernel_kobj); 22569d8e138SGreg Kroah-Hartman if (!security_kobj) 22669d8e138SGreg Kroah-Hartman return -EINVAL; 227b67dbf9dSGreg KH 228b67dbf9dSGreg KH retval = register_filesystem(&fs_type); 229b67dbf9dSGreg KH if (retval) 23078a2d906SGreg Kroah-Hartman kobject_put(security_kobj); 231b67dbf9dSGreg KH return retval; 232b67dbf9dSGreg KH } 233b67dbf9dSGreg KH 234b67dbf9dSGreg KH core_initcall(securityfs_init); 235b67dbf9dSGreg KH MODULE_LICENSE("GPL"); 236b67dbf9dSGreg KH 237