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
24#define SECURITYFS_MAGIC 0x73636673
25
26static struct vfsmount *mount;
27static int mount_count;
28
29
30
31
32
33static ssize_t default_read_file(struct file *file, char __user *buf,
34 size_t count, loff_t *ppos)
35{
36 return 0;
37}
38
39static ssize_t default_write_file(struct file *file, const char __user *buf,
40 size_t count, loff_t *ppos)
41{
42 return count;
43}
44
45static int default_open(struct inode *inode, struct file *file)
46{
47 if (inode->i_private)
48 file->private_data = inode->i_private;
49
50 return 0;
51}
52
53static const struct file_operations default_file_ops = {
54 .read = default_read_file,
55 .write = default_write_file,
56 .open = default_open,
57};
58
59static struct inode *get_inode(struct super_block *sb, int mode, dev_t dev)
60{
61 struct inode *inode = new_inode(sb);
62
63 if (inode) {
64 inode->i_mode = mode;
65 inode->i_uid = 0;
66 inode->i_gid = 0;
67 inode->i_blocks = 0;
68 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
69 switch (mode & S_IFMT) {
70 default:
71 init_special_inode(inode, mode, dev);
72 break;
73 case S_IFREG:
74 inode->i_fop = &default_file_ops;
75 break;
76 case S_IFDIR:
77 inode->i_op = &simple_dir_inode_operations;
78 inode->i_fop = &simple_dir_operations;
79
80
81 inc_nlink(inode);
82 break;
83 }
84 }
85 return inode;
86}
87
88
89static int mknod(struct inode *dir, struct dentry *dentry,
90 int mode, dev_t dev)
91{
92 struct inode *inode;
93 int error = -EPERM;
94
95 if (dentry->d_inode)
96 return -EEXIST;
97
98 inode = get_inode(dir->i_sb, mode, dev);
99 if (inode) {
100 d_instantiate(dentry, inode);
101 dget(dentry);
102 error = 0;
103 }
104 return error;
105}
106
107static int mkdir(struct inode *dir, struct dentry *dentry, int mode)
108{
109 int res;
110
111 mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
112 res = mknod(dir, dentry, mode, 0);
113 if (!res)
114 inc_nlink(dir);
115 return res;
116}
117
118static int create(struct inode *dir, struct dentry *dentry, int mode)
119{
120 mode = (mode & S_IALLUGO) | S_IFREG;
121 return mknod(dir, dentry, mode, 0);
122}
123
124static inline int positive(struct dentry *dentry)
125{
126 return dentry->d_inode && !d_unhashed(dentry);
127}
128
129static int fill_super(struct super_block *sb, void *data, int silent)
130{
131 static struct tree_descr files[] = {{""}};
132
133 return simple_fill_super(sb, SECURITYFS_MAGIC, files);
134}
135
136static int get_sb(struct file_system_type *fs_type,
137 int flags, const char *dev_name,
138 void *data, struct vfsmount *mnt)
139{
140 return get_sb_single(fs_type, flags, data, fill_super, mnt);
141}
142
143static struct file_system_type fs_type = {
144 .owner = THIS_MODULE,
145 .name = "securityfs",
146 .get_sb = get_sb,
147 .kill_sb = kill_litter_super,
148};
149
150static int create_by_name(const char *name, mode_t mode,
151 struct dentry *parent,
152 struct dentry **dentry)
153{
154 int error = 0;
155
156 *dentry = NULL;
157
158
159
160
161
162
163 if (!parent ) {
164 if (mount && mount->mnt_sb) {
165 parent = mount->mnt_sb->s_root;
166 }
167 }
168 if (!parent) {
169 pr_debug("securityfs: Ah! can not find a parent!\n");
170 return -EFAULT;
171 }
172
173 mutex_lock(&parent->d_inode->i_mutex);
174 *dentry = lookup_one_len(name, parent, strlen(name));
175 if (!IS_ERR(dentry)) {
176 if ((mode & S_IFMT) == S_IFDIR)
177 error = mkdir(parent->d_inode, *dentry, mode);
178 else
179 error = create(parent->d_inode, *dentry, mode);
180 } else
181 error = PTR_ERR(dentry);
182 mutex_unlock(&parent->d_inode->i_mutex);
183
184 return error;
185}
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216struct dentry *securityfs_create_file(const char *name, mode_t mode,
217 struct dentry *parent, void *data,
218 const struct file_operations *fops)
219{
220 struct dentry *dentry = NULL;
221 int error;
222
223 pr_debug("securityfs: creating file '%s'\n",name);
224
225 error = simple_pin_fs(&fs_type, &mount, &mount_count);
226 if (error) {
227 dentry = ERR_PTR(error);
228 goto exit;
229 }
230
231 error = create_by_name(name, mode, parent, &dentry);
232 if (error) {
233 dentry = ERR_PTR(error);
234 simple_release_fs(&mount, &mount_count);
235 goto exit;
236 }
237
238 if (dentry->d_inode) {
239 if (fops)
240 dentry->d_inode->i_fop = fops;
241 if (data)
242 dentry->d_inode->i_private = data;
243 }
244exit:
245 return dentry;
246}
247EXPORT_SYMBOL_GPL(securityfs_create_file);
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)
271{
272 return securityfs_create_file(name,
273 S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
274 parent, NULL, NULL);
275}
276EXPORT_SYMBOL_GPL(securityfs_create_dir);
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292void securityfs_remove(struct dentry *dentry)
293{
294 struct dentry *parent;
295
296 if (!dentry)
297 return;
298
299 parent = dentry->d_parent;
300 if (!parent || !parent->d_inode)
301 return;
302
303 mutex_lock(&parent->d_inode->i_mutex);
304 if (positive(dentry)) {
305 if (dentry->d_inode) {
306 if (S_ISDIR(dentry->d_inode->i_mode))
307 simple_rmdir(parent->d_inode, dentry);
308 else
309 simple_unlink(parent->d_inode, dentry);
310 dput(dentry);
311 }
312 }
313 mutex_unlock(&parent->d_inode->i_mutex);
314 simple_release_fs(&mount, &mount_count);
315}
316EXPORT_SYMBOL_GPL(securityfs_remove);
317
318static decl_subsys(security, NULL, NULL);
319
320static int __init securityfs_init(void)
321{
322 int retval;
323
324 kobj_set_kset_s(&security_subsys, kernel_subsys);
325 retval = subsystem_register(&security_subsys);
326 if (retval)
327 return retval;
328
329 retval = register_filesystem(&fs_type);
330 if (retval)
331 subsystem_unregister(&security_subsys);
332 return retval;
333}
334
335core_initcall(securityfs_init);
336MODULE_LICENSE("GPL");
337
338