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 .llseek = noop_llseek,
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_ino = get_next_ino();
65 inode->i_mode = mode;
66 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
67 switch (mode & S_IFMT) {
68 default:
69 init_special_inode(inode, mode, dev);
70 break;
71 case S_IFREG:
72 inode->i_fop = &default_file_ops;
73 break;
74 case S_IFDIR:
75 inode->i_op = &simple_dir_inode_operations;
76 inode->i_fop = &simple_dir_operations;
77
78
79 inc_nlink(inode);
80 break;
81 }
82 }
83 return inode;
84}
85
86
87static int mknod(struct inode *dir, struct dentry *dentry,
88 int mode, dev_t dev)
89{
90 struct inode *inode;
91 int error = -ENOMEM;
92
93 if (dentry->d_inode)
94 return -EEXIST;
95
96 inode = get_inode(dir->i_sb, mode, dev);
97 if (inode) {
98 d_instantiate(dentry, inode);
99 dget(dentry);
100 error = 0;
101 }
102 return error;
103}
104
105static int mkdir(struct inode *dir, struct dentry *dentry, int mode)
106{
107 int res;
108
109 mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
110 res = mknod(dir, dentry, mode, 0);
111 if (!res)
112 inc_nlink(dir);
113 return res;
114}
115
116static int create(struct inode *dir, struct dentry *dentry, int mode)
117{
118 mode = (mode & S_IALLUGO) | S_IFREG;
119 return mknod(dir, dentry, mode, 0);
120}
121
122static inline int positive(struct dentry *dentry)
123{
124 return dentry->d_inode && !d_unhashed(dentry);
125}
126
127static int fill_super(struct super_block *sb, void *data, int silent)
128{
129 static struct tree_descr files[] = {{""}};
130
131 return simple_fill_super(sb, SECURITYFS_MAGIC, files);
132}
133
134static struct dentry *get_sb(struct file_system_type *fs_type,
135 int flags, const char *dev_name,
136 void *data)
137{
138 return mount_single(fs_type, flags, data, fill_super);
139}
140
141static struct file_system_type fs_type = {
142 .owner = THIS_MODULE,
143 .name = "securityfs",
144 .mount = get_sb,
145 .kill_sb = kill_litter_super,
146};
147
148static int create_by_name(const char *name, mode_t mode,
149 struct dentry *parent,
150 struct dentry **dentry)
151{
152 int error = 0;
153
154 *dentry = NULL;
155
156
157
158
159
160
161 if (!parent)
162 parent = mount->mnt_sb->s_root;
163
164 mutex_lock(&parent->d_inode->i_mutex);
165 *dentry = lookup_one_len(name, parent, strlen(name));
166 if (!IS_ERR(*dentry)) {
167 if ((mode & S_IFMT) == S_IFDIR)
168 error = mkdir(parent->d_inode, *dentry, mode);
169 else
170 error = create(parent->d_inode, *dentry, mode);
171 if (error)
172 dput(*dentry);
173 } else
174 error = PTR_ERR(*dentry);
175 mutex_unlock(&parent->d_inode->i_mutex);
176
177 return error;
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
206
207
208struct dentry *securityfs_create_file(const char *name, mode_t mode,
209 struct dentry *parent, void *data,
210 const struct file_operations *fops)
211{
212 struct dentry *dentry = NULL;
213 int error;
214
215 pr_debug("securityfs: creating file '%s'\n",name);
216
217 error = simple_pin_fs(&fs_type, &mount, &mount_count);
218 if (error) {
219 dentry = ERR_PTR(error);
220 goto exit;
221 }
222
223 error = create_by_name(name, mode, parent, &dentry);
224 if (error) {
225 dentry = ERR_PTR(error);
226 simple_release_fs(&mount, &mount_count);
227 goto exit;
228 }
229
230 if (dentry->d_inode) {
231 if (fops)
232 dentry->d_inode->i_fop = fops;
233 if (data)
234 dentry->d_inode->i_private = data;
235 }
236exit:
237 return dentry;
238}
239EXPORT_SYMBOL_GPL(securityfs_create_file);
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)
263{
264 return securityfs_create_file(name,
265 S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
266 parent, NULL, NULL);
267}
268EXPORT_SYMBOL_GPL(securityfs_create_dir);
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283void securityfs_remove(struct dentry *dentry)
284{
285 struct dentry *parent;
286
287 if (!dentry || IS_ERR(dentry))
288 return;
289
290 parent = dentry->d_parent;
291 if (!parent || !parent->d_inode)
292 return;
293
294 mutex_lock(&parent->d_inode->i_mutex);
295 if (positive(dentry)) {
296 if (dentry->d_inode) {
297 if (S_ISDIR(dentry->d_inode->i_mode))
298 simple_rmdir(parent->d_inode, dentry);
299 else
300 simple_unlink(parent->d_inode, dentry);
301 dput(dentry);
302 }
303 }
304 mutex_unlock(&parent->d_inode->i_mutex);
305 simple_release_fs(&mount, &mount_count);
306}
307EXPORT_SYMBOL_GPL(securityfs_remove);
308
309static struct kobject *security_kobj;
310
311static int __init securityfs_init(void)
312{
313 int retval;
314
315 security_kobj = kobject_create_and_add("security", kernel_kobj);
316 if (!security_kobj)
317 return -EINVAL;
318
319 retval = register_filesystem(&fs_type);
320 if (retval)
321 kobject_put(security_kobj);
322 return retval;
323}
324
325core_initcall(securityfs_init);
326MODULE_LICENSE("GPL");
327
328