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 = -EPERM;
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 } else
170 error = PTR_ERR(*dentry);
171 mutex_unlock(&parent->d_inode->i_mutex);
172
173 return error;
174}
175
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
204struct dentry *securityfs_create_file(const char *name, mode_t mode,
205 struct dentry *parent, void *data,
206 const struct file_operations *fops)
207{
208 struct dentry *dentry = NULL;
209 int error;
210
211 pr_debug("securityfs: creating file '%s'\n",name);
212
213 error = simple_pin_fs(&fs_type, &mount, &mount_count);
214 if (error) {
215 dentry = ERR_PTR(error);
216 goto exit;
217 }
218
219 error = create_by_name(name, mode, parent, &dentry);
220 if (error) {
221 dentry = ERR_PTR(error);
222 simple_release_fs(&mount, &mount_count);
223 goto exit;
224 }
225
226 if (dentry->d_inode) {
227 if (fops)
228 dentry->d_inode->i_fop = fops;
229 if (data)
230 dentry->d_inode->i_private = data;
231 }
232exit:
233 return dentry;
234}
235EXPORT_SYMBOL_GPL(securityfs_create_file);
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)
259{
260 return securityfs_create_file(name,
261 S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
262 parent, NULL, NULL);
263}
264EXPORT_SYMBOL_GPL(securityfs_create_dir);
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279void securityfs_remove(struct dentry *dentry)
280{
281 struct dentry *parent;
282
283 if (!dentry || IS_ERR(dentry))
284 return;
285
286 parent = dentry->d_parent;
287 if (!parent || !parent->d_inode)
288 return;
289
290 mutex_lock(&parent->d_inode->i_mutex);
291 if (positive(dentry)) {
292 if (dentry->d_inode) {
293 if (S_ISDIR(dentry->d_inode->i_mode))
294 simple_rmdir(parent->d_inode, dentry);
295 else
296 simple_unlink(parent->d_inode, dentry);
297 dput(dentry);
298 }
299 }
300 mutex_unlock(&parent->d_inode->i_mutex);
301 simple_release_fs(&mount, &mount_count);
302}
303EXPORT_SYMBOL_GPL(securityfs_remove);
304
305static struct kobject *security_kobj;
306
307static int __init securityfs_init(void)
308{
309 int retval;
310
311 security_kobj = kobject_create_and_add("security", kernel_kobj);
312 if (!security_kobj)
313 return -EINVAL;
314
315 retval = register_filesystem(&fs_type);
316 if (retval)
317 kobject_put(security_kobj);
318 return retval;
319}
320
321core_initcall(securityfs_init);
322MODULE_LICENSE("GPL");
323
324