at v2.6.30 9.0 kB view raw
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/magic.h> 24 25static struct vfsmount *mount; 26static int mount_count; 27 28/* 29 * TODO: 30 * I think I can get rid of these default_file_ops, but not quite sure... 31 */ 32static ssize_t default_read_file(struct file *file, char __user *buf, 33 size_t count, loff_t *ppos) 34{ 35 return 0; 36} 37 38static ssize_t default_write_file(struct file *file, const char __user *buf, 39 size_t count, loff_t *ppos) 40{ 41 return count; 42} 43 44static int default_open(struct inode *inode, struct file *file) 45{ 46 if (inode->i_private) 47 file->private_data = inode->i_private; 48 49 return 0; 50} 51 52static const struct file_operations default_file_ops = { 53 .read = default_read_file, 54 .write = default_write_file, 55 .open = default_open, 56}; 57 58static struct inode *get_inode(struct super_block *sb, int mode, dev_t dev) 59{ 60 struct inode *inode = new_inode(sb); 61 62 if (inode) { 63 inode->i_mode = mode; 64 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 65 switch (mode & S_IFMT) { 66 default: 67 init_special_inode(inode, mode, dev); 68 break; 69 case S_IFREG: 70 inode->i_fop = &default_file_ops; 71 break; 72 case S_IFDIR: 73 inode->i_op = &simple_dir_inode_operations; 74 inode->i_fop = &simple_dir_operations; 75 76 /* directory inodes start off with i_nlink == 2 (for "." entry) */ 77 inc_nlink(inode); 78 break; 79 } 80 } 81 return inode; 82} 83 84/* SMP-safe */ 85static int mknod(struct inode *dir, struct dentry *dentry, 86 int mode, dev_t dev) 87{ 88 struct inode *inode; 89 int error = -EPERM; 90 91 if (dentry->d_inode) 92 return -EEXIST; 93 94 inode = get_inode(dir->i_sb, mode, dev); 95 if (inode) { 96 d_instantiate(dentry, inode); 97 dget(dentry); 98 error = 0; 99 } 100 return error; 101} 102 103static int mkdir(struct inode *dir, struct dentry *dentry, int mode) 104{ 105 int res; 106 107 mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; 108 res = mknod(dir, dentry, mode, 0); 109 if (!res) 110 inc_nlink(dir); 111 return res; 112} 113 114static int create(struct inode *dir, struct dentry *dentry, int mode) 115{ 116 mode = (mode & S_IALLUGO) | S_IFREG; 117 return mknod(dir, dentry, mode, 0); 118} 119 120static inline int positive(struct dentry *dentry) 121{ 122 return dentry->d_inode && !d_unhashed(dentry); 123} 124 125static int fill_super(struct super_block *sb, void *data, int silent) 126{ 127 static struct tree_descr files[] = {{""}}; 128 129 return simple_fill_super(sb, SECURITYFS_MAGIC, files); 130} 131 132static int get_sb(struct file_system_type *fs_type, 133 int flags, const char *dev_name, 134 void *data, struct vfsmount *mnt) 135{ 136 return get_sb_single(fs_type, flags, data, fill_super, mnt); 137} 138 139static struct file_system_type fs_type = { 140 .owner = THIS_MODULE, 141 .name = "securityfs", 142 .get_sb = get_sb, 143 .kill_sb = kill_litter_super, 144}; 145 146static int create_by_name(const char *name, mode_t mode, 147 struct dentry *parent, 148 struct dentry **dentry) 149{ 150 int error = 0; 151 152 *dentry = NULL; 153 154 /* If the parent is not specified, we create it in the root. 155 * We need the root dentry to do this, which is in the super 156 * block. A pointer to that is in the struct vfsmount that we 157 * have around. 158 */ 159 if (!parent ) { 160 if (mount && mount->mnt_sb) { 161 parent = mount->mnt_sb->s_root; 162 } 163 } 164 if (!parent) { 165 pr_debug("securityfs: Ah! can not find a parent!\n"); 166 return -EFAULT; 167 } 168 169 mutex_lock(&parent->d_inode->i_mutex); 170 *dentry = lookup_one_len(name, parent, strlen(name)); 171 if (!IS_ERR(dentry)) { 172 if ((mode & S_IFMT) == S_IFDIR) 173 error = mkdir(parent->d_inode, *dentry, mode); 174 else 175 error = create(parent->d_inode, *dentry, mode); 176 } else 177 error = PTR_ERR(dentry); 178 mutex_unlock(&parent->d_inode->i_mutex); 179 180 return error; 181} 182 183/** 184 * securityfs_create_file - create a file in the securityfs filesystem 185 * 186 * @name: a pointer to a string containing the name of the file to create. 187 * @mode: the permission that the file should have 188 * @parent: a pointer to the parent dentry for this file. This should be a 189 * directory dentry if set. If this parameter is %NULL, then the 190 * file will be created in the root of the securityfs filesystem. 191 * @data: a pointer to something that the caller will want to get to later 192 * on. The inode.i_private pointer will point to this value on 193 * the open() call. 194 * @fops: a pointer to a struct file_operations that should be used for 195 * this file. 196 * 197 * This is the basic "create a file" function for securityfs. It allows for a 198 * wide range of flexibility in creating a file, or a directory (if you 199 * want to create a directory, the securityfs_create_dir() function is 200 * recommended to be used instead). 201 * 202 * This function returns a pointer to a dentry if it succeeds. This 203 * pointer must be passed to the securityfs_remove() function when the file is 204 * to be removed (no automatic cleanup happens if your module is unloaded, 205 * you are responsible here). If an error occurs, the function will return 206 * the erorr value (via ERR_PTR). 207 * 208 * If securityfs is not enabled in the kernel, the value %-ENODEV is 209 * returned. 210 */ 211struct dentry *securityfs_create_file(const char *name, mode_t mode, 212 struct dentry *parent, void *data, 213 const struct file_operations *fops) 214{ 215 struct dentry *dentry = NULL; 216 int error; 217 218 pr_debug("securityfs: creating file '%s'\n",name); 219 220 error = simple_pin_fs(&fs_type, &mount, &mount_count); 221 if (error) { 222 dentry = ERR_PTR(error); 223 goto exit; 224 } 225 226 error = create_by_name(name, mode, parent, &dentry); 227 if (error) { 228 dentry = ERR_PTR(error); 229 simple_release_fs(&mount, &mount_count); 230 goto exit; 231 } 232 233 if (dentry->d_inode) { 234 if (fops) 235 dentry->d_inode->i_fop = fops; 236 if (data) 237 dentry->d_inode->i_private = data; 238 } 239exit: 240 return dentry; 241} 242EXPORT_SYMBOL_GPL(securityfs_create_file); 243 244/** 245 * securityfs_create_dir - create a directory in the securityfs filesystem 246 * 247 * @name: a pointer to a string containing the name of the directory to 248 * create. 249 * @parent: a pointer to the parent dentry for this file. This should be a 250 * directory dentry if set. If this parameter is %NULL, then the 251 * directory will be created in the root of the securityfs filesystem. 252 * 253 * This function creates a directory in securityfs with the given @name. 254 * 255 * This function returns a pointer to a dentry if it succeeds. This 256 * pointer must be passed to the securityfs_remove() function when the file is 257 * to be removed (no automatic cleanup happens if your module is unloaded, 258 * you are responsible here). If an error occurs, %NULL will be returned. 259 * 260 * If securityfs is not enabled in the kernel, the value %-ENODEV is 261 * returned. It is not wise to check for this value, but rather, check for 262 * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling 263 * code. 264 */ 265struct dentry *securityfs_create_dir(const char *name, struct dentry *parent) 266{ 267 return securityfs_create_file(name, 268 S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, 269 parent, NULL, NULL); 270} 271EXPORT_SYMBOL_GPL(securityfs_create_dir); 272 273/** 274 * securityfs_remove - removes a file or directory from the securityfs filesystem 275 * 276 * @dentry: a pointer to a the dentry of the file or directory to be removed. 277 * 278 * This function removes a file or directory in securityfs that was previously 279 * created with a call to another securityfs function (like 280 * securityfs_create_file() or variants thereof.) 281 * 282 * This function is required to be called in order for the file to be 283 * removed. No automatic cleanup of files will happen when a module is 284 * removed; you are responsible here. 285 */ 286void securityfs_remove(struct dentry *dentry) 287{ 288 struct dentry *parent; 289 290 if (!dentry) 291 return; 292 293 parent = dentry->d_parent; 294 if (!parent || !parent->d_inode) 295 return; 296 297 mutex_lock(&parent->d_inode->i_mutex); 298 if (positive(dentry)) { 299 if (dentry->d_inode) { 300 if (S_ISDIR(dentry->d_inode->i_mode)) 301 simple_rmdir(parent->d_inode, dentry); 302 else 303 simple_unlink(parent->d_inode, dentry); 304 dput(dentry); 305 } 306 } 307 mutex_unlock(&parent->d_inode->i_mutex); 308 simple_release_fs(&mount, &mount_count); 309} 310EXPORT_SYMBOL_GPL(securityfs_remove); 311 312static struct kobject *security_kobj; 313 314static int __init securityfs_init(void) 315{ 316 int retval; 317 318 security_kobj = kobject_create_and_add("security", kernel_kobj); 319 if (!security_kobj) 320 return -EINVAL; 321 322 retval = register_filesystem(&fs_type); 323 if (retval) 324 kobject_put(security_kobj); 325 return retval; 326} 327 328core_initcall(securityfs_init); 329MODULE_LICENSE("GPL"); 330