1 // SPDX-License-Identifier: GPL-2.0-only << 2 /* 1 /* 3 * fs/anon_inodes.c 2 * fs/anon_inodes.c 4 * 3 * 5 * Copyright (C) 2007 Davide Libenzi <davide 4 * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org> 6 * 5 * 7 * Thanks to Arnd Bergmann for code review an 6 * Thanks to Arnd Bergmann for code review and suggestions. 8 * More changes for Thomas Gleixner suggestio 7 * More changes for Thomas Gleixner suggestions. 9 * 8 * 10 */ 9 */ 11 10 12 #include <linux/cred.h> 11 #include <linux/cred.h> 13 #include <linux/file.h> 12 #include <linux/file.h> 14 #include <linux/poll.h> 13 #include <linux/poll.h> 15 #include <linux/sched.h> 14 #include <linux/sched.h> 16 #include <linux/init.h> 15 #include <linux/init.h> 17 #include <linux/fs.h> 16 #include <linux/fs.h> 18 #include <linux/mount.h> 17 #include <linux/mount.h> 19 #include <linux/module.h> 18 #include <linux/module.h> 20 #include <linux/kernel.h> 19 #include <linux/kernel.h> 21 #include <linux/magic.h> 20 #include <linux/magic.h> 22 #include <linux/anon_inodes.h> 21 #include <linux/anon_inodes.h> 23 #include <linux/pseudo_fs.h> << 24 22 25 #include <linux/uaccess.h> 23 #include <linux/uaccess.h> 26 24 27 static struct vfsmount *anon_inode_mnt __ro_af !! 25 static struct vfsmount *anon_inode_mnt __read_mostly; 28 static struct inode *anon_inode_inode __ro_aft !! 26 static struct inode *anon_inode_inode; 29 27 30 /* 28 /* 31 * anon_inodefs_dname() is called from d_path( 29 * anon_inodefs_dname() is called from d_path(). 32 */ 30 */ 33 static char *anon_inodefs_dname(struct dentry 31 static char *anon_inodefs_dname(struct dentry *dentry, char *buffer, int buflen) 34 { 32 { 35 return dynamic_dname(buffer, buflen, " !! 33 return dynamic_dname(dentry, buffer, buflen, "anon_inode:%s", 36 dentry->d_name 34 dentry->d_name.name); 37 } 35 } 38 36 39 static const struct dentry_operations anon_ino 37 static const struct dentry_operations anon_inodefs_dentry_operations = { 40 .d_dname = anon_inodefs_dname, 38 .d_dname = anon_inodefs_dname, 41 }; 39 }; 42 40 43 static int anon_inodefs_init_fs_context(struct !! 41 static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type, >> 42 int flags, const char *dev_name, void *data) 44 { 43 { 45 struct pseudo_fs_context *ctx = init_p !! 44 return mount_pseudo(fs_type, "anon_inode:", NULL, 46 if (!ctx) !! 45 &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC); 47 return -ENOMEM; << 48 ctx->dops = &anon_inodefs_dentry_opera << 49 return 0; << 50 } 46 } 51 47 52 static struct file_system_type anon_inode_fs_t 48 static struct file_system_type anon_inode_fs_type = { 53 .name = "anon_inodefs", 49 .name = "anon_inodefs", 54 .init_fs_context = anon_inodefs_init_f !! 50 .mount = anon_inodefs_mount, 55 .kill_sb = kill_anon_super, 51 .kill_sb = kill_anon_super, 56 }; 52 }; 57 53 58 static struct inode *anon_inode_make_secure_in << 59 const char *name, << 60 const struct inode *context_inode) << 61 { << 62 struct inode *inode; << 63 const struct qstr qname = QSTR_INIT(na << 64 int error; << 65 << 66 inode = alloc_anon_inode(anon_inode_mn << 67 if (IS_ERR(inode)) << 68 return inode; << 69 inode->i_flags &= ~S_PRIVATE; << 70 error = security_inode_init_security_a << 71 if (error) { << 72 iput(inode); << 73 return ERR_PTR(error); << 74 } << 75 return inode; << 76 } << 77 << 78 static struct file *__anon_inode_getfile(const << 79 const << 80 void << 81 const << 82 bool << 83 { << 84 struct inode *inode; << 85 struct file *file; << 86 << 87 if (fops->owner && !try_module_get(fop << 88 return ERR_PTR(-ENOENT); << 89 << 90 if (make_inode) { << 91 inode = anon_inode_make_secure << 92 if (IS_ERR(inode)) { << 93 file = ERR_CAST(inode) << 94 goto err; << 95 } << 96 } else { << 97 inode = anon_inode_inode; << 98 if (IS_ERR(inode)) { << 99 file = ERR_PTR(-ENODEV << 100 goto err; << 101 } << 102 /* << 103 * We know the anon_inode inod << 104 * greater than zero, so ihold << 105 */ << 106 ihold(inode); << 107 } << 108 << 109 file = alloc_file_pseudo(inode, anon_i << 110 flags & (O_AC << 111 if (IS_ERR(file)) << 112 goto err_iput; << 113 << 114 file->f_mapping = inode->i_mapping; << 115 << 116 file->private_data = priv; << 117 << 118 return file; << 119 << 120 err_iput: << 121 iput(inode); << 122 err: << 123 module_put(fops->owner); << 124 return file; << 125 } << 126 << 127 /** 54 /** 128 * anon_inode_getfile - creates a new file ins 55 * anon_inode_getfile - creates a new file instance by hooking it up to an 129 * anonymous inode, and a 56 * anonymous inode, and a dentry that describe the "class" 130 * of the file 57 * of the file 131 * 58 * 132 * @name: [in] name of the "class" of th 59 * @name: [in] name of the "class" of the new file 133 * @fops: [in] file operations for the n 60 * @fops: [in] file operations for the new file 134 * @priv: [in] private data for the new 61 * @priv: [in] private data for the new file (will be file's private_data) 135 * @flags: [in] flags 62 * @flags: [in] flags 136 * 63 * 137 * Creates a new file by hooking it on a singl 64 * Creates a new file by hooking it on a single inode. This is useful for files 138 * that do not need to have a full-fledged ino 65 * that do not need to have a full-fledged inode in order to operate correctly. 139 * All the files created with anon_inode_getfi 66 * All the files created with anon_inode_getfile() will share a single inode, 140 * hence saving memory and avoiding code dupli 67 * hence saving memory and avoiding code duplication for the file/inode/dentry 141 * setup. Returns the newly created file* or 68 * setup. Returns the newly created file* or an error pointer. 142 */ 69 */ 143 struct file *anon_inode_getfile(const char *na 70 struct file *anon_inode_getfile(const char *name, 144 const struct f 71 const struct file_operations *fops, 145 void *priv, in 72 void *priv, int flags) 146 { 73 { 147 return __anon_inode_getfile(name, fops << 148 } << 149 EXPORT_SYMBOL_GPL(anon_inode_getfile); << 150 << 151 /** << 152 * anon_inode_getfile_fmode - creates a new fi << 153 * anonymous inode, and a << 154 * of the file << 155 * << 156 * @name: [in] name of the "class" of th << 157 * @fops: [in] file operations for the n << 158 * @priv: [in] private data for the new << 159 * @flags: [in] flags << 160 * @f_mode: [in] fmode << 161 * << 162 * Creates a new file by hooking it on a singl << 163 * that do not need to have a full-fledged ino << 164 * All the files created with anon_inode_getfi << 165 * hence saving memory and avoiding code dupli << 166 * setup. Allows setting the fmode. Returns th << 167 * pointer. << 168 */ << 169 struct file *anon_inode_getfile_fmode(const ch << 170 const struct f << 171 void *priv, in << 172 { << 173 struct file *file; 74 struct file *file; 174 75 175 file = __anon_inode_getfile(name, fops !! 76 if (IS_ERR(anon_inode_inode)) 176 if (!IS_ERR(file)) !! 77 return ERR_PTR(-ENODEV); 177 file->f_mode |= f_mode; !! 78 >> 79 if (fops->owner && !try_module_get(fops->owner)) >> 80 return ERR_PTR(-ENOENT); >> 81 >> 82 /* >> 83 * We know the anon_inode inode count is always greater than zero, >> 84 * so ihold() is safe. >> 85 */ >> 86 ihold(anon_inode_inode); >> 87 file = alloc_file_pseudo(anon_inode_inode, anon_inode_mnt, name, >> 88 flags & (O_ACCMODE | O_NONBLOCK), fops); >> 89 if (IS_ERR(file)) >> 90 goto err; 178 91 >> 92 file->f_mapping = anon_inode_inode->i_mapping; >> 93 >> 94 file->private_data = priv; >> 95 >> 96 return file; >> 97 >> 98 err: >> 99 iput(anon_inode_inode); >> 100 module_put(fops->owner); 179 return file; 101 return file; 180 } 102 } 181 EXPORT_SYMBOL_GPL(anon_inode_getfile_fmode); !! 103 EXPORT_SYMBOL_GPL(anon_inode_getfile); 182 104 183 /** 105 /** 184 * anon_inode_create_getfile - Like anon_inode !! 106 * anon_inode_getfd - creates a new file instance by hooking it up to an 185 * !S_PRIVATE anon !! 107 * anonymous inode, and a dentry that describe the "class" 186 * singleton anon !! 108 * of the file 187 * inode_init_secu << 188 * 109 * 189 * @name: [in] name of the "class" of th 110 * @name: [in] name of the "class" of the new file 190 * @fops: [in] file operations for the n 111 * @fops: [in] file operations for the new file 191 * @priv: [in] private data for the new 112 * @priv: [in] private data for the new file (will be file's private_data) 192 * @flags: [in] flags 113 * @flags: [in] flags 193 * @context_inode: << 194 * [in] the logical relationship << 195 * << 196 * Create a new anonymous inode and file pair. << 197 * reasons: << 198 * << 199 * - for the inode to have its own security co << 200 * policy on the inode's creation; << 201 * 114 * 202 * - if the caller needs a unique inode, for e !! 115 * Creates a new file by hooking it on a single inode. This is useful for files 203 * the size returned by fstat() !! 116 * that do not need to have a full-fledged inode in order to operate correctly. 204 * !! 117 * All the files created with anon_inode_getfd() will share a single inode, 205 * The LSM may use @context_inode in inode_ini !! 118 * hence saving memory and avoiding code duplication for the file/inode/dentry 206 * reference to it is not held. !! 119 * setup. Returns new descriptor or an error code. 207 * << 208 * Returns the newly created file* or an error << 209 */ 120 */ 210 struct file *anon_inode_create_getfile(const c !! 121 int anon_inode_getfd(const char *name, const struct file_operations *fops, 211 const s !! 122 void *priv, int flags) 212 void *p << 213 const s << 214 { << 215 return __anon_inode_getfile(name, fops << 216 context_in << 217 } << 218 EXPORT_SYMBOL_GPL(anon_inode_create_getfile); << 219 << 220 static int __anon_inode_getfd(const char *name << 221 const struct fil << 222 void *priv, int << 223 const struct ino << 224 bool make_inode) << 225 { 123 { 226 int error, fd; 124 int error, fd; 227 struct file *file; 125 struct file *file; 228 126 229 error = get_unused_fd_flags(flags); 127 error = get_unused_fd_flags(flags); 230 if (error < 0) 128 if (error < 0) 231 return error; 129 return error; 232 fd = error; 130 fd = error; 233 131 234 file = __anon_inode_getfile(name, fops !! 132 file = anon_inode_getfile(name, fops, priv, flags); 235 make_inode << 236 if (IS_ERR(file)) { 133 if (IS_ERR(file)) { 237 error = PTR_ERR(file); 134 error = PTR_ERR(file); 238 goto err_put_unused_fd; 135 goto err_put_unused_fd; 239 } 136 } 240 fd_install(fd, file); 137 fd_install(fd, file); 241 138 242 return fd; 139 return fd; 243 140 244 err_put_unused_fd: 141 err_put_unused_fd: 245 put_unused_fd(fd); 142 put_unused_fd(fd); 246 return error; 143 return error; 247 } 144 } 248 << 249 /** << 250 * anon_inode_getfd - creates a new file insta << 251 * an anonymous inode and a << 252 * the "class" of the file << 253 * << 254 * @name: [in] name of the "class" of th << 255 * @fops: [in] file operations for the n << 256 * @priv: [in] private data for the new << 257 * @flags: [in] flags << 258 * << 259 * Creates a new file by hooking it on a singl << 260 * useful for files that do not need to have a << 261 * order to operate correctly. All the files << 262 * anon_inode_getfd() will use the same single << 263 * memory use and avoiding code duplication fo << 264 * setup. Returns a newly created file descri << 265 */ << 266 int anon_inode_getfd(const char *name, const s << 267 void *priv, int flags) << 268 { << 269 return __anon_inode_getfd(name, fops, << 270 } << 271 EXPORT_SYMBOL_GPL(anon_inode_getfd); 145 EXPORT_SYMBOL_GPL(anon_inode_getfd); 272 << 273 /** << 274 * anon_inode_create_getfd - Like anon_inode_g << 275 * !S_PRIVATE anon inode rather than reuse the << 276 * the inode_init_security_anon() LSM hook. << 277 * << 278 * @name: [in] name of the "class" of th << 279 * @fops: [in] file operations for the n << 280 * @priv: [in] private data for the new << 281 * @flags: [in] flags << 282 * @context_inode: << 283 * [in] the logical relationship << 284 * << 285 * Create a new anonymous inode and file pair. << 286 * reasons: << 287 * << 288 * - for the inode to have its own security co << 289 * policy on the inode's creation; << 290 * << 291 * - if the caller needs a unique inode, for e << 292 * the size returned by fstat() << 293 * << 294 * The LSM may use @context_inode in inode_ini << 295 * reference to it is not held. << 296 * << 297 * Returns a newly created file descriptor or << 298 */ << 299 int anon_inode_create_getfd(const char *name, << 300 void *priv, int fl << 301 const struct inode << 302 { << 303 return __anon_inode_getfd(name, fops, << 304 } << 305 << 306 146 307 static int __init anon_inode_init(void) 147 static int __init anon_inode_init(void) 308 { 148 { 309 anon_inode_mnt = kern_mount(&anon_inod 149 anon_inode_mnt = kern_mount(&anon_inode_fs_type); 310 if (IS_ERR(anon_inode_mnt)) 150 if (IS_ERR(anon_inode_mnt)) 311 panic("anon_inode_init() kerne 151 panic("anon_inode_init() kernel mount failed (%ld)\n", PTR_ERR(anon_inode_mnt)); 312 152 313 anon_inode_inode = alloc_anon_inode(an 153 anon_inode_inode = alloc_anon_inode(anon_inode_mnt->mnt_sb); 314 if (IS_ERR(anon_inode_inode)) 154 if (IS_ERR(anon_inode_inode)) 315 panic("anon_inode_init() inode 155 panic("anon_inode_init() inode allocation failed (%ld)\n", PTR_ERR(anon_inode_inode)); 316 156 317 return 0; 157 return 0; 318 } 158 } 319 159 320 fs_initcall(anon_inode_init); 160 fs_initcall(anon_inode_init); 321 161 322 162
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.