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