1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
30
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
77 inc_nlink(inode);
78 break;
79 }
80 }
81 return inode;
82}
83
84
85static int mknod(struct inode *dir, struct dentry *dentry,
86 int mode, dev_t dev)
87{
88 struct inode *inode;
89 int error = -ENOMEM;
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
155
156
157
158
159 if (!parent)
160 parent = mount->mnt_sb->s_root;
161
162 mutex_lock(&parent->d_inode->i_mutex);
163 *dentry = lookup_one_len(name, parent, strlen(name));
164 if (!IS_ERR(*dentry)) {
165 if ((mode & S_IFMT) == S_IFDIR)
166 error = mkdir(parent->d_inode, *dentry, mode);
167 else
168 error = create(parent->d_inode, *dentry, mode);
169 if (error)
170 dput(*dentry);
171 } else
172 error = PTR_ERR(*dentry);
173 mutex_unlock(&parent->d_inode->i_mutex);
174
175 return error;
176}
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206struct dentry *securityfs_create_file(const char *name, mode_t mode,
207 struct dentry *parent, void *data,
208 const struct file_operations *fops)
209{
210 struct dentry *dentry = NULL;
211 int error;
212
213 pr_debug("securityfs: creating file '%s'\n",name);
214
215 error = simple_pin_fs(&fs_type, &mount, &mount_count);
216 if (error) {
217 dentry = ERR_PTR(error);
218 goto exit;
219 }
220
221 error = create_by_name(name, mode, parent, &dentry);
222 if (error) {
223 dentry = ERR_PTR(error);
224 simple_release_fs(&mount, &mount_count);
225 goto exit;
226 }
227
228 if (dentry->d_inode) {
229 if (fops)
230 dentry->d_inode->i_fop = fops;
231 if (data)
232 dentry->d_inode->i_private = data;
233 }
234exit:
235 return dentry;
236}
237EXPORT_SYMBOL_GPL(securityfs_create_file);
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)
261{
262 return securityfs_create_file(name,
263 S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
264 parent, NULL, NULL);
265}
266EXPORT_SYMBOL_GPL(securityfs_create_dir);
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281void securityfs_remove(struct dentry *dentry)
282{
283 struct dentry *parent;
284
285 if (!dentry || IS_ERR(dentry))
286 return;
287
288 parent = dentry->d_parent;
289 if (!parent || !parent->d_inode)
290 return;
291
292 mutex_lock(&parent->d_inode->i_mutex);
293 if (positive(dentry)) {
294 if (dentry->d_inode) {
295 if (S_ISDIR(dentry->d_inode->i_mode))
296 simple_rmdir(parent->d_inode, dentry);
297 else
298 simple_unlink(parent->d_inode, dentry);
299 dput(dentry);
300 }
301 }
302 mutex_unlock(&parent->d_inode->i_mutex);
303 simple_release_fs(&mount, &mount_count);
304}
305EXPORT_SYMBOL_GPL(securityfs_remove);
306
307static struct kobject *security_kobj;
308
309static int __init securityfs_init(void)
310{
311 int retval;
312
313 security_kobj = kobject_create_and_add("security", kernel_kobj);
314 if (!security_kobj)
315 return -EINVAL;
316
317 retval = register_filesystem(&fs_type);
318 if (retval)
319 kobject_put(security_kobj);
320 return retval;
321}
322
323core_initcall(securityfs_init);
324MODULE_LICENSE("GPL");
325
326