457c899653991 (Thomas Gleixner 2019-05-19 13:08:55 +0100 1) // SPDX-License-Identifier: GPL-2.0-only
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 2) /*
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 3) * fs/anon_inodes.c
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 4) *
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 5) * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 6) *
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 7) * Thanks to Arnd Bergmann for code review and suggestions.
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 8) * More changes for Thomas Gleixner suggestions.
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 9) *
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 10) */
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 11)
a99bbaf5ee6ba (Alexey Dobriyan 2009-10-04 16:11:37 +0400 12) #include <linux/cred.h>
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 13) #include <linux/file.h>
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 14) #include <linux/poll.h>
a99bbaf5ee6ba (Alexey Dobriyan 2009-10-04 16:11:37 +0400 15) #include <linux/sched.h>
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 16) #include <linux/init.h>
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 17) #include <linux/fs.h>
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 18) #include <linux/mount.h>
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 19) #include <linux/module.h>
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 20) #include <linux/kernel.h>
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 21) #include <linux/magic.h>
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 22) #include <linux/anon_inodes.h>
33cada40b51f0 (David Howells 2019-03-25 16:38:23 +0000 23) #include <linux/pseudo_fs.h>
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 24)
7c0f6ba682b9c (Linus Torvalds 2016-12-24 11:46:01 -0800 25) #include <linux/uaccess.h>
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 26)
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 27) static struct vfsmount *anon_inode_mnt __read_mostly;
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 28) static struct inode *anon_inode_inode;
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 29)
b9aff027b2c1d (Nicholas Piggin 2009-11-20 14:28:35 -0800 30) /*
b9aff027b2c1d (Nicholas Piggin 2009-11-20 14:28:35 -0800 31) * anon_inodefs_dname() is called from d_path().
b9aff027b2c1d (Nicholas Piggin 2009-11-20 14:28:35 -0800 32) */
b9aff027b2c1d (Nicholas Piggin 2009-11-20 14:28:35 -0800 33) static char *anon_inodefs_dname(struct dentry *dentry, char *buffer, int buflen)
b9aff027b2c1d (Nicholas Piggin 2009-11-20 14:28:35 -0800 34) {
b9aff027b2c1d (Nicholas Piggin 2009-11-20 14:28:35 -0800 35) return dynamic_dname(dentry, buffer, buflen, "anon_inode:%s",
b9aff027b2c1d (Nicholas Piggin 2009-11-20 14:28:35 -0800 36) dentry->d_name.name);
b9aff027b2c1d (Nicholas Piggin 2009-11-20 14:28:35 -0800 37) }
b9aff027b2c1d (Nicholas Piggin 2009-11-20 14:28:35 -0800 38)
c74a1cbb3cac3 (Al Viro 2011-01-12 16:59:34 -0500 39) static const struct dentry_operations anon_inodefs_dentry_operations = {
c74a1cbb3cac3 (Al Viro 2011-01-12 16:59:34 -0500 40) .d_dname = anon_inodefs_dname,
c74a1cbb3cac3 (Al Viro 2011-01-12 16:59:34 -0500 41) };
c74a1cbb3cac3 (Al Viro 2011-01-12 16:59:34 -0500 42)
33cada40b51f0 (David Howells 2019-03-25 16:38:23 +0000 43) static int anon_inodefs_init_fs_context(struct fs_context *fc)
ca7068c41a8d4 (Al Viro 2012-03-17 02:52:29 -0400 44) {
33cada40b51f0 (David Howells 2019-03-25 16:38:23 +0000 45) struct pseudo_fs_context *ctx = init_pseudo(fc, ANON_INODE_FS_MAGIC);
33cada40b51f0 (David Howells 2019-03-25 16:38:23 +0000 46) if (!ctx)
33cada40b51f0 (David Howells 2019-03-25 16:38:23 +0000 47) return -ENOMEM;
33cada40b51f0 (David Howells 2019-03-25 16:38:23 +0000 48) ctx->dops = &anon_inodefs_dentry_operations;
33cada40b51f0 (David Howells 2019-03-25 16:38:23 +0000 49) return 0;
ca7068c41a8d4 (Al Viro 2012-03-17 02:52:29 -0400 50) }
ca7068c41a8d4 (Al Viro 2012-03-17 02:52:29 -0400 51)
ca7068c41a8d4 (Al Viro 2012-03-17 02:52:29 -0400 52) static struct file_system_type anon_inode_fs_type = {
ca7068c41a8d4 (Al Viro 2012-03-17 02:52:29 -0400 53) .name = "anon_inodefs",
33cada40b51f0 (David Howells 2019-03-25 16:38:23 +0000 54) .init_fs_context = anon_inodefs_init_fs_context,
ca7068c41a8d4 (Al Viro 2012-03-17 02:52:29 -0400 55) .kill_sb = kill_anon_super,
ca7068c41a8d4 (Al Viro 2012-03-17 02:52:29 -0400 56) };
ca7068c41a8d4 (Al Viro 2012-03-17 02:52:29 -0400 57)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 58) static struct inode *anon_inode_make_secure_inode(
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 59) const char *name,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 60) const struct inode *context_inode)
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 61) {
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 62) struct inode *inode;
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 63) const struct qstr qname = QSTR_INIT(name, strlen(name));
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 64) int error;
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 65)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 66) inode = alloc_anon_inode(anon_inode_mnt->mnt_sb);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 67) if (IS_ERR(inode))
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 68) return inode;
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 69) inode->i_flags &= ~S_PRIVATE;
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 70) error = security_inode_init_security_anon(inode, &qname, context_inode);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 71) if (error) {
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 72) iput(inode);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 73) return ERR_PTR(error);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 74) }
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 75) return inode;
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 76) }
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 77)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 78) static struct file *__anon_inode_getfile(const char *name,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 79) const struct file_operations *fops,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 80) void *priv, int flags,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 81) const struct inode *context_inode,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 82) bool secure)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 83) {
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 84) struct inode *inode;
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 85) struct file *file;
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 86)
e3a2a0d4e5ace (Christian Borntraeger 2008-12-02 11:16:03 +0100 87) if (fops->owner && !try_module_get(fops->owner))
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 88) return ERR_PTR(-ENOENT);
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 89)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 90) if (secure) {
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 91) inode = anon_inode_make_secure_inode(name, context_inode);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 92) if (IS_ERR(inode)) {
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 93) file = ERR_CAST(inode);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 94) goto err;
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 95) }
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 96) } else {
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 97) inode = anon_inode_inode;
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 98) if (IS_ERR(inode)) {
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 99) file = ERR_PTR(-ENODEV);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 100) goto err;
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 101) }
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 102) /*
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 103) * We know the anon_inode inode count is always
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 104) * greater than zero, so ihold() is safe.
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 105) */
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 106) ihold(inode);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 107) }
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 108)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 109) file = alloc_file_pseudo(inode, anon_inode_mnt, name,
52c91f8b3b1f5 (Al Viro 2018-06-09 09:58:23 -0400 110) flags & (O_ACCMODE | O_NONBLOCK), fops);
39b6525274574 (Anatol Pomozov 2012-09-12 20:11:55 -0700 111) if (IS_ERR(file))
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 112) goto err_iput;
52c91f8b3b1f5 (Al Viro 2018-06-09 09:58:23 -0400 113)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 114) file->f_mapping = inode->i_mapping;
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 115)
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 116) file->private_data = priv;
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 117)
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 118) return file;
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 119)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 120) err_iput:
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 121) iput(inode);
52c91f8b3b1f5 (Al Viro 2018-06-09 09:58:23 -0400 122) err:
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 123) module_put(fops->owner);
39b6525274574 (Anatol Pomozov 2012-09-12 20:11:55 -0700 124) return file;
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 125) }
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 126)
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 127) /**
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 128) * anon_inode_getfile - creates a new file instance by hooking it up to an
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 129) * anonymous inode, and a dentry that describe the "class"
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 130) * of the file
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 131) *
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 132) * @name: [in] name of the "class" of the new file
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 133) * @fops: [in] file operations for the new file
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 134) * @priv: [in] private data for the new file (will be file's private_data)
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 135) * @flags: [in] flags
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 136) *
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 137) * Creates a new file by hooking it on a single inode. This is useful for files
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 138) * that do not need to have a full-fledged inode in order to operate correctly.
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 139) * All the files created with anon_inode_getfile() will share a single inode,
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 140) * hence saving memory and avoiding code duplication for the file/inode/dentry
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 141) * setup. Returns the newly created file* or an error pointer.
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 142) */
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 143) struct file *anon_inode_getfile(const char *name,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 144) const struct file_operations *fops,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 145) void *priv, int flags)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 146) {
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 147) return __anon_inode_getfile(name, fops, priv, flags, NULL, false);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 148) }
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 149) EXPORT_SYMBOL_GPL(anon_inode_getfile);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 150)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 151) static int __anon_inode_getfd(const char *name,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 152) const struct file_operations *fops,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 153) void *priv, int flags,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 154) const struct inode *context_inode,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 155) bool secure)
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 156) {
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 157) int error, fd;
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 158) struct file *file;
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 159)
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 160) error = get_unused_fd_flags(flags);
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 161) if (error < 0)
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 162) return error;
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 163) fd = error;
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 164)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 165) file = __anon_inode_getfile(name, fops, priv, flags, context_inode,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 166) secure);
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 167) if (IS_ERR(file)) {
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 168) error = PTR_ERR(file);
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 169) goto err_put_unused_fd;
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 170) }
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 171) fd_install(fd, file);
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 172)
2030a42cecd4d (Al Viro 2008-02-23 06:46:49 -0500 173) return fd;
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 174)
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 175) err_put_unused_fd:
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 176) put_unused_fd(fd);
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 177) return error;
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 178) }
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 179)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 180) /**
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 181) * anon_inode_getfd - creates a new file instance by hooking it up to
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 182) * an anonymous inode and a dentry that describe
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 183) * the "class" of the file
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 184) *
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 185) * @name: [in] name of the "class" of the new file
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 186) * @fops: [in] file operations for the new file
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 187) * @priv: [in] private data for the new file (will be file's private_data)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 188) * @flags: [in] flags
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 189) *
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 190) * Creates a new file by hooking it on a single inode. This is
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 191) * useful for files that do not need to have a full-fledged inode in
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 192) * order to operate correctly. All the files created with
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 193) * anon_inode_getfd() will use the same singleton inode, reducing
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 194) * memory use and avoiding code duplication for the file/inode/dentry
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 195) * setup. Returns a newly created file descriptor or an error code.
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 196) */
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 197) int anon_inode_getfd(const char *name, const struct file_operations *fops,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 198) void *priv, int flags)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 199) {
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 200) return __anon_inode_getfd(name, fops, priv, flags, NULL, false);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 201) }
d6d281684913d (Avi Kivity 2007-06-28 08:38:16 -0400 202) EXPORT_SYMBOL_GPL(anon_inode_getfd);
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 203)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 204) /**
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 205) * anon_inode_getfd_secure - Like anon_inode_getfd(), but creates a new
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 206) * !S_PRIVATE anon inode rather than reuse the singleton anon inode, and calls
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 207) * the inode_init_security_anon() LSM hook. This allows the inode to have its
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 208) * own security context and for a LSM to reject creation of the inode.
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 209) *
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 210) * @name: [in] name of the "class" of the new file
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 211) * @fops: [in] file operations for the new file
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 212) * @priv: [in] private data for the new file (will be file's private_data)
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 213) * @flags: [in] flags
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 214) * @context_inode:
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 215) * [in] the logical relationship with the new inode (optional)
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 216) *
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 217) * The LSM may use @context_inode in inode_init_security_anon(), but a
365982aba1f26 (Lukas Bulwahn 2021-01-15 13:03:42 +0100 218) * reference to it is not held.
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 219) */
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 220) int anon_inode_getfd_secure(const char *name, const struct file_operations *fops,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 221) void *priv, int flags,
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 222) const struct inode *context_inode)
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 223) {
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 224) return __anon_inode_getfd(name, fops, priv, flags, context_inode, true);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 225) }
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 226) EXPORT_SYMBOL_GPL(anon_inode_getfd_secure);
e7e832ce6fa76 (Daniel Colascione 2021-01-08 14:22:21 -0800 227)
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 228) static int __init anon_inode_init(void)
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 229) {
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 230) anon_inode_mnt = kern_mount(&anon_inode_fs_type);
75c5a52da3fc2 (Jan Kara 2014-03-26 06:20:14 +0100 231) if (IS_ERR(anon_inode_mnt))
75c5a52da3fc2 (Jan Kara 2014-03-26 06:20:14 +0100 232) panic("anon_inode_init() kernel mount failed (%ld)\n", PTR_ERR(anon_inode_mnt));
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 233)
75c5a52da3fc2 (Jan Kara 2014-03-26 06:20:14 +0100 234) anon_inode_inode = alloc_anon_inode(anon_inode_mnt->mnt_sb);
75c5a52da3fc2 (Jan Kara 2014-03-26 06:20:14 +0100 235) if (IS_ERR(anon_inode_inode))
75c5a52da3fc2 (Jan Kara 2014-03-26 06:20:14 +0100 236) panic("anon_inode_init() inode allocation failed (%ld)\n", PTR_ERR(anon_inode_inode));
75c5a52da3fc2 (Jan Kara 2014-03-26 06:20:14 +0100 237)
75c5a52da3fc2 (Jan Kara 2014-03-26 06:20:14 +0100 238) return 0;
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 239) }
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 240)
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 241) fs_initcall(anon_inode_init);
5dc8bf8132d59 (Davide Libenzi 2007-05-10 22:23:11 -0700 242)