aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/apparmorfs.c132
-rw-r--r--security/apparmor/include/apparmorfs.h24
2 files changed, 114 insertions, 42 deletions
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index e39df6d43779..1e22bb3a8851 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -144,36 +144,103 @@ static const struct file_operations aa_fs_profile_remove = {
144 144
145/** Base file system setup **/ 145/** Base file system setup **/
146 146
147static struct dentry *aa_fs_dentry __initdata; 147static struct aa_fs_entry aa_fs_entry_apparmor[] = {
148 AA_FS_FILE_FOPS(".load", 0640, &aa_fs_profile_load),
149 AA_FS_FILE_FOPS(".replace", 0640, &aa_fs_profile_replace),
150 AA_FS_FILE_FOPS(".remove", 0640, &aa_fs_profile_remove),
151 { }
152};
148 153
149static void __init aafs_remove(const char *name) 154static struct aa_fs_entry aa_fs_entry =
150{ 155 AA_FS_DIR("apparmor", aa_fs_entry_apparmor);
151 struct dentry *dentry;
152 156
153 dentry = lookup_one_len(name, aa_fs_dentry, strlen(name)); 157/**
154 if (!IS_ERR(dentry)) { 158 * aafs_create_file - create a file entry in the apparmor securityfs
155 securityfs_remove(dentry); 159 * @fs_file: aa_fs_entry to build an entry for (NOT NULL)
156 dput(dentry); 160 * @parent: the parent dentry in the securityfs
161 *
162 * Use aafs_remove_file to remove entries created with this fn.
163 */
164static int __init aafs_create_file(struct aa_fs_entry *fs_file,
165 struct dentry *parent)
166{
167 int error = 0;
168
169 fs_file->dentry = securityfs_create_file(fs_file->name,
170 S_IFREG | fs_file->mode,
171 parent, fs_file,
172 fs_file->file_ops);
173 if (IS_ERR(fs_file->dentry)) {
174 error = PTR_ERR(fs_file->dentry);
175 fs_file->dentry = NULL;
157 } 176 }
177 return error;
158} 178}
159 179
160/** 180/**
161 * aafs_create - create an entry in the apparmor filesystem 181 * aafs_create_dir - recursively create a directory entry in the securityfs
162 * @name: name of the entry (NOT NULL) 182 * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL)
163 * @mask: file permission mask of the file 183 * @parent: the parent dentry in the securityfs
164 * @fops: file operations for the file (NOT NULL)
165 * 184 *
166 * Used aafs_remove to remove entries created with this fn. 185 * Use aafs_remove_dir to remove entries created with this fn.
167 */ 186 */
168static int __init aafs_create(const char *name, umode_t mask, 187static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
169 const struct file_operations *fops) 188 struct dentry *parent)
170{ 189{
171 struct dentry *dentry; 190 int error;
191 struct aa_fs_entry *fs_file;
172 192
173 dentry = securityfs_create_file(name, S_IFREG | mask, aa_fs_dentry, 193 fs_dir->dentry = securityfs_create_dir(fs_dir->name, parent);
174 NULL, fops); 194 if (IS_ERR(fs_dir->dentry)) {
195 error = PTR_ERR(fs_dir->dentry);
196 fs_dir->dentry = NULL;
197 goto failed;
198 }
175 199
176 return IS_ERR(dentry) ? PTR_ERR(dentry) : 0; 200 for (fs_file = fs_dir->v.files; fs_file->name; ++fs_file) {
201 if (fs_file->v_type == AA_FS_TYPE_DIR)
202 error = aafs_create_dir(fs_file, fs_dir->dentry);
203 else
204 error = aafs_create_file(fs_file, fs_dir->dentry);
205 if (error)
206 goto failed;
207 }
208
209 return 0;
210
211failed:
212 return error;
213}
214
215/**
216 * aafs_remove_file - drop a single file entry in the apparmor securityfs
217 * @fs_file: aa_fs_entry to detach from the securityfs (NOT NULL)
218 */
219static void __init aafs_remove_file(struct aa_fs_entry *fs_file)
220{
221 if (!fs_file->dentry)
222 return;
223
224 securityfs_remove(fs_file->dentry);
225 fs_file->dentry = NULL;
226}
227
228/**
229 * aafs_remove_dir - recursively drop a directory entry from the securityfs
230 * @fs_dir: aa_fs_entry (and all child entries) to detach (NOT NULL)
231 */
232static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir)
233{
234 struct aa_fs_entry *fs_file;
235
236 for (fs_file = fs_dir->v.files; fs_file->name; ++fs_file) {
237 if (fs_file->v_type == AA_FS_TYPE_DIR)
238 aafs_remove_dir(fs_file);
239 else
240 aafs_remove_file(fs_file);
241 }
242
243 aafs_remove_file(fs_dir);
177} 244}
178 245
179/** 246/**
@@ -183,14 +250,7 @@ static int __init aafs_create(const char *name, umode_t mask,
183 */ 250 */
184void __init aa_destroy_aafs(void) 251void __init aa_destroy_aafs(void)
185{ 252{
186 if (aa_fs_dentry) { 253 aafs_remove_dir(&aa_fs_entry);
187 aafs_remove(".remove");
188 aafs_remove(".replace");
189 aafs_remove(".load");
190
191 securityfs_remove(aa_fs_dentry);
192 aa_fs_dentry = NULL;
193 }
194} 254}
195 255
196/** 256/**
@@ -207,25 +267,13 @@ static int __init aa_create_aafs(void)
207 if (!apparmor_initialized) 267 if (!apparmor_initialized)
208 return 0; 268 return 0;
209 269
210 if (aa_fs_dentry) { 270 if (aa_fs_entry.dentry) {
211 AA_ERROR("%s: AppArmor securityfs already exists\n", __func__); 271 AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
212 return -EEXIST; 272 return -EEXIST;
213 } 273 }
214 274
215 aa_fs_dentry = securityfs_create_dir("apparmor", NULL); 275 /* Populate fs tree. */
216 if (IS_ERR(aa_fs_dentry)) { 276 error = aafs_create_dir(&aa_fs_entry, NULL);
217 error = PTR_ERR(aa_fs_dentry);
218 aa_fs_dentry = NULL;
219 goto error;
220 }
221
222 error = aafs_create(".load", 0640, &aa_fs_profile_load);
223 if (error)
224 goto error;
225 error = aafs_create(".replace", 0640, &aa_fs_profile_replace);
226 if (error)
227 goto error;
228 error = aafs_create(".remove", 0640, &aa_fs_profile_remove);
229 if (error) 277 if (error)
230 goto error; 278 goto error;
231 279
diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
index cb1e93a114d7..4fdf02f26a3a 100644
--- a/security/apparmor/include/apparmorfs.h
+++ b/security/apparmor/include/apparmorfs.h
@@ -15,6 +15,30 @@
15#ifndef __AA_APPARMORFS_H 15#ifndef __AA_APPARMORFS_H
16#define __AA_APPARMORFS_H 16#define __AA_APPARMORFS_H
17 17
18enum aa_fs_type {
19 AA_FS_TYPE_FOPS,
20 AA_FS_TYPE_DIR,
21};
22
23struct aa_fs_entry;
24
25struct aa_fs_entry {
26 const char *name;
27 struct dentry *dentry;
28 umode_t mode;
29 enum aa_fs_type v_type;
30 union {
31 struct aa_fs_entry *files;
32 } v;
33 const struct file_operations *file_ops;
34};
35
36#define AA_FS_FILE_FOPS(_name, _mode, _fops) \
37 { .name = (_name), .v_type = AA_FS_TYPE_FOPS, \
38 .mode = (_mode), .file_ops = (_fops) }
39#define AA_FS_DIR(_name, _value) \
40 { .name = (_name), .v_type = AA_FS_TYPE_DIR, .v.files = (_value) }
41
18extern void __init aa_destroy_aafs(void); 42extern void __init aa_destroy_aafs(void);
19 43
20#endif /* __AA_APPARMORFS_H */ 44#endif /* __AA_APPARMORFS_H */