hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/fs/anon_inodes.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * fs/anon_inodes.c
34 *
....@@ -19,6 +20,7 @@
1920 #include <linux/kernel.h>
2021 #include <linux/magic.h>
2122 #include <linux/anon_inodes.h>
23
+#include <linux/pseudo_fs.h>
2224
2325 #include <linux/uaccess.h>
2426
....@@ -38,18 +40,89 @@
3840 .d_dname = anon_inodefs_dname,
3941 };
4042
41
-static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
42
- int flags, const char *dev_name, void *data)
43
+static int anon_inodefs_init_fs_context(struct fs_context *fc)
4344 {
44
- return mount_pseudo(fs_type, "anon_inode:", NULL,
45
- &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC);
45
+ struct pseudo_fs_context *ctx = init_pseudo(fc, ANON_INODE_FS_MAGIC);
46
+ if (!ctx)
47
+ return -ENOMEM;
48
+ ctx->dops = &anon_inodefs_dentry_operations;
49
+ return 0;
4650 }
4751
4852 static struct file_system_type anon_inode_fs_type = {
4953 .name = "anon_inodefs",
50
- .mount = anon_inodefs_mount,
54
+ .init_fs_context = anon_inodefs_init_fs_context,
5155 .kill_sb = kill_anon_super,
5256 };
57
+
58
+static struct inode *anon_inode_make_secure_inode(
59
+ const char *name,
60
+ const struct inode *context_inode)
61
+{
62
+ struct inode *inode;
63
+ const struct qstr qname = QSTR_INIT(name, strlen(name));
64
+ int error;
65
+
66
+ inode = alloc_anon_inode(anon_inode_mnt->mnt_sb);
67
+ if (IS_ERR(inode))
68
+ return inode;
69
+ inode->i_flags &= ~S_PRIVATE;
70
+ error = security_inode_init_security_anon(inode, &qname, context_inode);
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 char *name,
79
+ const struct file_operations *fops,
80
+ void *priv, int flags,
81
+ const struct inode *context_inode,
82
+ bool secure)
83
+{
84
+ struct inode *inode;
85
+ struct file *file;
86
+
87
+ if (fops->owner && !try_module_get(fops->owner))
88
+ return ERR_PTR(-ENOENT);
89
+
90
+ if (secure) {
91
+ inode = anon_inode_make_secure_inode(name, context_inode);
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 inode count is always
104
+ * greater than zero, so ihold() is safe.
105
+ */
106
+ ihold(inode);
107
+ }
108
+
109
+ file = alloc_file_pseudo(inode, anon_inode_mnt, name,
110
+ flags & (O_ACCMODE | O_NONBLOCK), fops);
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
+}
53126
54127 /**
55128 * anon_inode_getfile - creates a new file instance by hooking it up to an
....@@ -71,55 +144,15 @@
71144 const struct file_operations *fops,
72145 void *priv, int flags)
73146 {
74
- struct file *file;
75
-
76
- if (IS_ERR(anon_inode_inode))
77
- return ERR_PTR(-ENODEV);
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;
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);
101
- return file;
147
+ return __anon_inode_getfile(name, fops, priv, flags, NULL, false);
102148 }
103149 EXPORT_SYMBOL_GPL(anon_inode_getfile);
104150
105
-/**
106
- * anon_inode_getfd - creates a new file instance by hooking it up to an
107
- * anonymous inode, and a dentry that describe the "class"
108
- * of the file
109
- *
110
- * @name: [in] name of the "class" of the new file
111
- * @fops: [in] file operations for the new file
112
- * @priv: [in] private data for the new file (will be file's private_data)
113
- * @flags: [in] flags
114
- *
115
- * Creates a new file by hooking it on a single inode. This is useful for files
116
- * that do not need to have a full-fledged inode in order to operate correctly.
117
- * All the files created with anon_inode_getfd() will share a single inode,
118
- * hence saving memory and avoiding code duplication for the file/inode/dentry
119
- * setup. Returns new descriptor or an error code.
120
- */
121
-int anon_inode_getfd(const char *name, const struct file_operations *fops,
122
- void *priv, int flags)
151
+static int __anon_inode_getfd(const char *name,
152
+ const struct file_operations *fops,
153
+ void *priv, int flags,
154
+ const struct inode *context_inode,
155
+ bool secure)
123156 {
124157 int error, fd;
125158 struct file *file;
....@@ -129,7 +162,8 @@
129162 return error;
130163 fd = error;
131164
132
- file = anon_inode_getfile(name, fops, priv, flags);
165
+ file = __anon_inode_getfile(name, fops, priv, flags, context_inode,
166
+ secure);
133167 if (IS_ERR(file)) {
134168 error = PTR_ERR(file);
135169 goto err_put_unused_fd;
....@@ -142,8 +176,55 @@
142176 put_unused_fd(fd);
143177 return error;
144178 }
179
+
180
+/**
181
+ * anon_inode_getfd - creates a new file instance by hooking it up to
182
+ * an anonymous inode and a dentry that describe
183
+ * the "class" of the file
184
+ *
185
+ * @name: [in] name of the "class" of the new file
186
+ * @fops: [in] file operations for the new file
187
+ * @priv: [in] private data for the new file (will be file's private_data)
188
+ * @flags: [in] flags
189
+ *
190
+ * Creates a new file by hooking it on a single inode. This is
191
+ * useful for files that do not need to have a full-fledged inode in
192
+ * order to operate correctly. All the files created with
193
+ * anon_inode_getfd() will use the same singleton inode, reducing
194
+ * memory use and avoiding code duplication for the file/inode/dentry
195
+ * setup. Returns a newly created file descriptor or an error code.
196
+ */
197
+int anon_inode_getfd(const char *name, const struct file_operations *fops,
198
+ void *priv, int flags)
199
+{
200
+ return __anon_inode_getfd(name, fops, priv, flags, NULL, false);
201
+}
145202 EXPORT_SYMBOL_GPL(anon_inode_getfd);
146203
204
+/**
205
+ * anon_inode_getfd_secure - Like anon_inode_getfd(), but creates a new
206
+ * !S_PRIVATE anon inode rather than reuse the singleton anon inode, and calls
207
+ * the inode_init_security_anon() LSM hook. This allows the inode to have its
208
+ * own security context and for a LSM to reject creation of the inode.
209
+ *
210
+ * @name: [in] name of the "class" of the new file
211
+ * @fops: [in] file operations for the new file
212
+ * @priv: [in] private data for the new file (will be file's private_data)
213
+ * @flags: [in] flags
214
+ * @context_inode:
215
+ * [in] the logical relationship with the new inode (optional)
216
+ *
217
+ * The LSM may use @context_inode in inode_init_security_anon(), but a
218
+ * reference to it is not held.
219
+ */
220
+int anon_inode_getfd_secure(const char *name, const struct file_operations *fops,
221
+ void *priv, int flags,
222
+ const struct inode *context_inode)
223
+{
224
+ return __anon_inode_getfd(name, fops, priv, flags, context_inode, true);
225
+}
226
+EXPORT_SYMBOL_GPL(anon_inode_getfd_secure);
227
+
147228 static int __init anon_inode_init(void)
148229 {
149230 anon_inode_mnt = kern_mount(&anon_inode_fs_type);