1 /* 2 * inode.c - securityfs 3 * 4 * Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License version 8 * 2 as published by the Free Software Foundation. 9 * 10 * Based on fs/debugfs/inode.c which had the following copyright notice: 11 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> 12 * Copyright (C) 2004 IBM Inc. 13 */ 14 15 /* #define DEBUG */ 16 #include <linux/module.h> 17 #include <linux/fs.h> 18 #include <linux/mount.h> 19 #include <linux/pagemap.h> 20 #include <linux/init.h> 21 #include <linux/namei.h> 22 #include <linux/security.h> 23 #include <linux/lsm_hooks.h> 24 #include <linux/magic.h> 25 26 static struct vfsmount *mount; 27 static int mount_count; 28 29 static int fill_super(struct super_block *sb, void *data, int silent) 30 { 31 static struct tree_descr files[] = {{""}}; 32 33 return simple_fill_super(sb, SECURITYFS_MAGIC, files); 34 } 35 36 static struct dentry *get_sb(struct file_system_type *fs_type, 37 int flags, const char *dev_name, 38 void *data) 39 { 40 return mount_single(fs_type, flags, data, fill_super); 41 } 42 43 static struct file_system_type fs_type = { 44 .owner = THIS_MODULE, 45 .name = "securityfs", 46 .mount = get_sb, 47 .kill_sb = kill_litter_super, 48 }; 49 50 /** 51 * securityfs_create_file - create a file in the securityfs filesystem 52 * 53 * @name: a pointer to a string containing the name of the file to create. 54 * @mode: the permission that the file should have 55 * @parent: a pointer to the parent dentry for this file. This should be a 56 * directory dentry if set. If this parameter is %NULL, then the 57 * file will be created in the root of the securityfs filesystem. 58 * @data: a pointer to something that the caller will want to get to later 59 * on. The inode.i_private pointer will point to this value on 60 * the open() call. 61 * @fops: a pointer to a struct file_operations that should be used for 62 * this file. 63 * 64 * This is the basic "create a file" function for securityfs. It allows for a 65 * wide range of flexibility in creating a file, or a directory (if you 66 * want to create a directory, the securityfs_create_dir() function is 67 * recommended to be used instead). 68 * 69 * This function returns a pointer to a dentry if it succeeds. This 70 * pointer must be passed to the securityfs_remove() function when the file is 71 * to be removed (no automatic cleanup happens if your module is unloaded, 72 * you are responsible here). If an error occurs, the function will return 73 * the error value (via ERR_PTR). 74 * 75 * If securityfs is not enabled in the kernel, the value %-ENODEV is 76 * returned. 77 */ 78 struct dentry *securityfs_create_file(const char *name, umode_t mode, 79 struct dentry *parent, void *data, 80 const struct file_operations *fops) 81 { 82 struct dentry *dentry; 83 int is_dir = S_ISDIR(mode); 84 struct inode *dir, *inode; 85 int error; 86 87 if (!is_dir) { 88 BUG_ON(!fops); 89 mode = (mode & S_IALLUGO) | S_IFREG; 90 } 91 92 pr_debug("securityfs: creating file '%s'\n",name); 93 94 error = simple_pin_fs(&fs_type, &mount, &mount_count); 95 if (error) 96 return ERR_PTR(error); 97 98 if (!parent) 99 parent = mount->mnt_root; 100 101 dir = d_inode(parent); 102 103 inode_lock(dir); 104 dentry = lookup_one_len(name, parent, strlen(name)); 105 if (IS_ERR(dentry)) 106 goto out; 107 108 if (d_really_is_positive(dentry)) { 109 error = -EEXIST; 110 goto out1; 111 } 112 113 inode = new_inode(dir->i_sb); 114 if (!inode) { 115 error = -ENOMEM; 116 goto out1; 117 } 118 119 inode->i_ino = get_next_ino(); 120 inode->i_mode = mode; 121 inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); 122 inode->i_private = data; 123 if (is_dir) { 124 inode->i_op = &simple_dir_inode_operations; 125 inode->i_fop = &simple_dir_operations; 126 inc_nlink(inode); 127 inc_nlink(dir); 128 } else { 129 inode->i_fop = fops; 130 } 131 d_instantiate(dentry, inode); 132 dget(dentry); 133 inode_unlock(dir); 134 return dentry; 135 136 out1: 137 dput(dentry); 138 dentry = ERR_PTR(error); 139 out: 140 inode_unlock(dir); 141 simple_release_fs(&mount, &mount_count); 142 return dentry; 143 } 144 EXPORT_SYMBOL_GPL(securityfs_create_file); 145 146 /** 147 * securityfs_create_dir - create a directory in the securityfs filesystem 148 * 149 * @name: a pointer to a string containing the name of the directory to 150 * create. 151 * @parent: a pointer to the parent dentry for this file. This should be a 152 * directory dentry if set. If this parameter is %NULL, then the 153 * directory will be created in the root of the securityfs filesystem. 154 * 155 * This function creates a directory in securityfs with the given @name. 156 * 157 * This function returns a pointer to a dentry if it succeeds. This 158 * pointer must be passed to the securityfs_remove() function when the file is 159 * to be removed (no automatic cleanup happens if your module is unloaded, 160 * you are responsible here). If an error occurs, the function will return 161 * the error value (via ERR_PTR). 162 * 163 * If securityfs is not enabled in the kernel, the value %-ENODEV is 164 * returned. 165 */ 166 struct dentry *securityfs_create_dir(const char *name, struct dentry *parent) 167 { 168 return securityfs_create_file(name, 169 S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, 170 parent, NULL, NULL); 171 } 172 EXPORT_SYMBOL_GPL(securityfs_create_dir); 173 174 /** 175 * securityfs_remove - removes a file or directory from the securityfs filesystem 176 * 177 * @dentry: a pointer to a the dentry of the file or directory to be removed. 178 * 179 * This function removes a file or directory in securityfs that was previously 180 * created with a call to another securityfs function (like 181 * securityfs_create_file() or variants thereof.) 182 * 183 * This function is required to be called in order for the file to be 184 * removed. No automatic cleanup of files will happen when a module is 185 * removed; you are responsible here. 186 */ 187 void securityfs_remove(struct dentry *dentry) 188 { 189 struct inode *dir; 190 191 if (!dentry || IS_ERR(dentry)) 192 return; 193 194 dir = d_inode(dentry->d_parent); 195 inode_lock(dir); 196 if (simple_positive(dentry)) { 197 if (d_is_dir(dentry)) 198 simple_rmdir(dir, dentry); 199 else 200 simple_unlink(dir, dentry); 201 dput(dentry); 202 } 203 inode_unlock(dir); 204 simple_release_fs(&mount, &mount_count); 205 } 206 EXPORT_SYMBOL_GPL(securityfs_remove); 207 208 #ifdef CONFIG_SECURITY 209 static struct dentry *lsm_dentry; 210 static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count, 211 loff_t *ppos) 212 { 213 return simple_read_from_buffer(buf, count, ppos, lsm_names, 214 strlen(lsm_names)); 215 } 216 217 static const struct file_operations lsm_ops = { 218 .read = lsm_read, 219 .llseek = generic_file_llseek, 220 }; 221 #endif 222 223 static int __init securityfs_init(void) 224 { 225 int retval; 226 227 retval = sysfs_create_mount_point(kernel_kobj, "security"); 228 if (retval) 229 return retval; 230 231 retval = register_filesystem(&fs_type); 232 if (retval) { 233 sysfs_remove_mount_point(kernel_kobj, "security"); 234 return retval; 235 } 236 #ifdef CONFIG_SECURITY 237 lsm_dentry = securityfs_create_file("lsm", 0444, NULL, NULL, 238 &lsm_ops); 239 #endif 240 return 0; 241 } 242 243 core_initcall(securityfs_init); 244 MODULE_LICENSE("GPL"); 245 246