apparmorfs.c (c6380ecd8e9bee7aba3d9a5a94b58168244c4a61) apparmorfs.c (56974a6fcfef69ee0825bd66ed13e92070ac5224)
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor /sys/kernel/security/apparmor interface functions
5 *
6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2010 Canonical Ltd.
8 *

--- 16 unchanged lines hidden (view full) ---

25#include <linux/fs.h>
26#include <linux/poll.h>
27#include <uapi/linux/major.h>
28#include <uapi/linux/magic.h>
29
30#include "include/apparmor.h"
31#include "include/apparmorfs.h"
32#include "include/audit.h"
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor /sys/kernel/security/apparmor interface functions
5 *
6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2010 Canonical Ltd.
8 *

--- 16 unchanged lines hidden (view full) ---

25#include <linux/fs.h>
26#include <linux/poll.h>
27#include <uapi/linux/major.h>
28#include <uapi/linux/magic.h>
29
30#include "include/apparmor.h"
31#include "include/apparmorfs.h"
32#include "include/audit.h"
33#include "include/context.h"
33#include "include/cred.h"
34#include "include/crypto.h"
35#include "include/ipc.h"
34#include "include/crypto.h"
35#include "include/ipc.h"
36#include "include/policy_ns.h"
37#include "include/label.h"
38#include "include/policy.h"
39#include "include/policy_ns.h"
40#include "include/resource.h"
41#include "include/policy_unpack.h"
42
43/*
44 * The apparmor filesystem interface used for policy load and introspection

--- 70 unchanged lines hidden (view full) ---

115
116#define AAFS_NAME "apparmorfs"
117static struct vfsmount *aafs_mnt;
118static int aafs_count;
119
120
121static int aafs_show_path(struct seq_file *seq, struct dentry *dentry)
122{
36#include "include/label.h"
37#include "include/policy.h"
38#include "include/policy_ns.h"
39#include "include/resource.h"
40#include "include/policy_unpack.h"
41
42/*
43 * The apparmor filesystem interface used for policy load and introspection

--- 70 unchanged lines hidden (view full) ---

114
115#define AAFS_NAME "apparmorfs"
116static struct vfsmount *aafs_mnt;
117static int aafs_count;
118
119
120static int aafs_show_path(struct seq_file *seq, struct dentry *dentry)
121{
123 struct inode *inode = d_inode(dentry);
124
125 seq_printf(seq, "%s:[%lu]", AAFS_NAME, inode->i_ino);
122 seq_printf(seq, "%s:[%lu]", AAFS_NAME, d_inode(dentry)->i_ino);
126 return 0;
127}
128
129static void aafs_evict_inode(struct inode *inode)
130{
131 truncate_inode_pages_final(&inode->i_data);
132 clear_inode(inode);
133 if (S_ISLNK(inode->i_mode))

--- 432 unchanged lines hidden (view full) ---

566 rev->ns = aa_get_ns(inode->i_private);
567 if (!rev->ns)
568 rev->ns = aa_get_current_ns();
569 file->private_data = rev;
570
571 return 0;
572}
573
123 return 0;
124}
125
126static void aafs_evict_inode(struct inode *inode)
127{
128 truncate_inode_pages_final(&inode->i_data);
129 clear_inode(inode);
130 if (S_ISLNK(inode->i_mode))

--- 432 unchanged lines hidden (view full) ---

563 rev->ns = aa_get_ns(inode->i_private);
564 if (!rev->ns)
565 rev->ns = aa_get_current_ns();
566 file->private_data = rev;
567
568 return 0;
569}
570
574static __poll_t ns_revision_poll(struct file *file, poll_table *pt)
571static unsigned int ns_revision_poll(struct file *file, poll_table *pt)
575{
576 struct aa_revision *rev = file->private_data;
572{
573 struct aa_revision *rev = file->private_data;
577 __poll_t mask = 0;
574 unsigned int mask = 0;
578
579 if (rev) {
580 mutex_lock_nested(&rev->ns->lock, rev->ns->level);
581 poll_wait(file, &rev->ns->wait, pt);
582 if (rev->last_read < rev->ns->revision)
575
576 if (rev) {
577 mutex_lock_nested(&rev->ns->lock, rev->ns->level);
578 poll_wait(file, &rev->ns->wait, pt);
579 if (rev->last_read < rev->ns->revision)
583 mask |= EPOLLIN | EPOLLRDNORM;
580 mask |= POLLIN | POLLRDNORM;
584 mutex_unlock(&rev->ns->lock);
585 }
586
587 return mask;
588}
589
590void __aa_bump_ns_revision(struct aa_ns *ns)
591{

--- 592 unchanged lines hidden (view full) ---

1184 end_current_label_crit_section(label);
1185
1186 return 0;
1187}
1188
1189static int seq_ns_name_show(struct seq_file *seq, void *v)
1190{
1191 struct aa_label *label = begin_current_label_crit_section();
581 mutex_unlock(&rev->ns->lock);
582 }
583
584 return mask;
585}
586
587void __aa_bump_ns_revision(struct aa_ns *ns)
588{

--- 592 unchanged lines hidden (view full) ---

1181 end_current_label_crit_section(label);
1182
1183 return 0;
1184}
1185
1186static int seq_ns_name_show(struct seq_file *seq, void *v)
1187{
1188 struct aa_label *label = begin_current_label_crit_section();
1192
1193 seq_printf(seq, "%s\n", aa_ns_name(labels_ns(label),
1194 labels_ns(label), true));
1189 seq_printf(seq, "%s\n", labels_ns(label)->base.name);
1195 end_current_label_crit_section(label);
1196
1197 return 0;
1198}
1199
1200SEQ_NS_FOPS(stacked);
1201SEQ_NS_FOPS(nsstacked);
1202SEQ_NS_FOPS(level);

--- 944 unchanged lines hidden (view full) ---

2147 { }
2148};
2149
2150static struct aa_sfs_entry aa_sfs_entry_signal[] = {
2151 AA_SFS_FILE_STRING("mask", AA_SFS_SIG_MASK),
2152 { }
2153};
2154
1190 end_current_label_crit_section(label);
1191
1192 return 0;
1193}
1194
1195SEQ_NS_FOPS(stacked);
1196SEQ_NS_FOPS(nsstacked);
1197SEQ_NS_FOPS(level);

--- 944 unchanged lines hidden (view full) ---

2142 { }
2143};
2144
2145static struct aa_sfs_entry aa_sfs_entry_signal[] = {
2146 AA_SFS_FILE_STRING("mask", AA_SFS_SIG_MASK),
2147 { }
2148};
2149
2150static struct aa_sfs_entry aa_sfs_entry_attach[] = {
2151 AA_SFS_FILE_BOOLEAN("xattr", 1),
2152 { }
2153};
2155static struct aa_sfs_entry aa_sfs_entry_domain[] = {
2156 AA_SFS_FILE_BOOLEAN("change_hat", 1),
2157 AA_SFS_FILE_BOOLEAN("change_hatv", 1),
2158 AA_SFS_FILE_BOOLEAN("change_onexec", 1),
2159 AA_SFS_FILE_BOOLEAN("change_profile", 1),
2160 AA_SFS_FILE_BOOLEAN("stack", 1),
2161 AA_SFS_FILE_BOOLEAN("fix_binfmt_elf_mmap", 1),
2154static struct aa_sfs_entry aa_sfs_entry_domain[] = {
2155 AA_SFS_FILE_BOOLEAN("change_hat", 1),
2156 AA_SFS_FILE_BOOLEAN("change_hatv", 1),
2157 AA_SFS_FILE_BOOLEAN("change_onexec", 1),
2158 AA_SFS_FILE_BOOLEAN("change_profile", 1),
2159 AA_SFS_FILE_BOOLEAN("stack", 1),
2160 AA_SFS_FILE_BOOLEAN("fix_binfmt_elf_mmap", 1),
2161 AA_SFS_FILE_BOOLEAN("post_nnp_subset", 1),
2162 AA_SFS_FILE_BOOLEAN("computed_longest_left", 1),
2163 AA_SFS_DIR("attach_conditions", aa_sfs_entry_attach),
2162 AA_SFS_FILE_STRING("version", "1.2"),
2163 { }
2164};
2165
2166static struct aa_sfs_entry aa_sfs_entry_versions[] = {
2167 AA_SFS_FILE_BOOLEAN("v5", 1),
2168 AA_SFS_FILE_BOOLEAN("v6", 1),
2169 AA_SFS_FILE_BOOLEAN("v7", 1),
2164 AA_SFS_FILE_STRING("version", "1.2"),
2165 { }
2166};
2167
2168static struct aa_sfs_entry aa_sfs_entry_versions[] = {
2169 AA_SFS_FILE_BOOLEAN("v5", 1),
2170 AA_SFS_FILE_BOOLEAN("v6", 1),
2171 AA_SFS_FILE_BOOLEAN("v7", 1),
2172 AA_SFS_FILE_BOOLEAN("v8", 1),
2170 { }
2171};
2172
2173static struct aa_sfs_entry aa_sfs_entry_policy[] = {
2174 AA_SFS_DIR("versions", aa_sfs_entry_versions),
2175 AA_SFS_FILE_BOOLEAN("set_load", 1),
2176 { }
2177};

--- 19 unchanged lines hidden (view full) ---

2197static struct aa_sfs_entry aa_sfs_entry_query[] = {
2198 AA_SFS_DIR("label", aa_sfs_entry_query_label),
2199 { }
2200};
2201static struct aa_sfs_entry aa_sfs_entry_features[] = {
2202 AA_SFS_DIR("policy", aa_sfs_entry_policy),
2203 AA_SFS_DIR("domain", aa_sfs_entry_domain),
2204 AA_SFS_DIR("file", aa_sfs_entry_file),
2173 { }
2174};
2175
2176static struct aa_sfs_entry aa_sfs_entry_policy[] = {
2177 AA_SFS_DIR("versions", aa_sfs_entry_versions),
2178 AA_SFS_FILE_BOOLEAN("set_load", 1),
2179 { }
2180};

--- 19 unchanged lines hidden (view full) ---

2200static struct aa_sfs_entry aa_sfs_entry_query[] = {
2201 AA_SFS_DIR("label", aa_sfs_entry_query_label),
2202 { }
2203};
2204static struct aa_sfs_entry aa_sfs_entry_features[] = {
2205 AA_SFS_DIR("policy", aa_sfs_entry_policy),
2206 AA_SFS_DIR("domain", aa_sfs_entry_domain),
2207 AA_SFS_DIR("file", aa_sfs_entry_file),
2208 AA_SFS_DIR("network_v8", aa_sfs_entry_network),
2205 AA_SFS_DIR("mount", aa_sfs_entry_mount),
2206 AA_SFS_DIR("namespaces", aa_sfs_entry_ns),
2207 AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
2208 AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit),
2209 AA_SFS_DIR("caps", aa_sfs_entry_caps),
2210 AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace),
2211 AA_SFS_DIR("signal", aa_sfs_entry_signal),
2212 AA_SFS_DIR("query", aa_sfs_entry_query),

--- 176 unchanged lines hidden (view full) ---

2389 path.mnt = mntget(aafs_mnt);
2390 path.dentry = dget(ns_dir(ns));
2391 nd_jump_link(&path);
2392 aa_put_ns(ns);
2393
2394 return NULL;
2395}
2396
2209 AA_SFS_DIR("mount", aa_sfs_entry_mount),
2210 AA_SFS_DIR("namespaces", aa_sfs_entry_ns),
2211 AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
2212 AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit),
2213 AA_SFS_DIR("caps", aa_sfs_entry_caps),
2214 AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace),
2215 AA_SFS_DIR("signal", aa_sfs_entry_signal),
2216 AA_SFS_DIR("query", aa_sfs_entry_query),

--- 176 unchanged lines hidden (view full) ---

2393 path.mnt = mntget(aafs_mnt);
2394 path.dentry = dget(ns_dir(ns));
2395 nd_jump_link(&path);
2396 aa_put_ns(ns);
2397
2398 return NULL;
2399}
2400
2397static int ns_get_name(char *buf, size_t size, struct aa_ns *ns,
2398 struct inode *inode)
2399{
2400 int res = snprintf(buf, size, "%s:[%lu]", AAFS_NAME, inode->i_ino);
2401
2402 if (res < 0 || res >= size)
2403 res = -ENOENT;
2404
2405 return res;
2406}
2407
2408static int policy_readlink(struct dentry *dentry, char __user *buffer,
2409 int buflen)
2410{
2401static int policy_readlink(struct dentry *dentry, char __user *buffer,
2402 int buflen)
2403{
2411 struct aa_ns *ns;
2412 char name[32];
2413 int res;
2414
2404 char name[32];
2405 int res;
2406
2415 ns = aa_get_current_ns();
2416 res = ns_get_name(name, sizeof(name), ns, d_inode(dentry));
2417 if (res >= 0)
2407 res = snprintf(name, sizeof(name), "%s:[%lu]", AAFS_NAME,
2408 d_inode(dentry)->i_ino);
2409 if (res > 0 && res < sizeof(name))
2418 res = readlink_copy(buffer, buflen, name);
2410 res = readlink_copy(buffer, buflen, name);
2419 aa_put_ns(ns);
2411 else
2412 res = -ENOENT;
2420
2421 return res;
2422}
2423
2424static const struct inode_operations policy_link_iops = {
2425 .readlink = policy_readlink,
2426 .get_link = policy_get_link,
2427};

--- 27 unchanged lines hidden (view full) ---

2455
2456 /* Populate fs tree. */
2457 error = entry_create_dir(&aa_sfs_entry, NULL);
2458 if (error)
2459 goto error;
2460
2461 dent = securityfs_create_file(".load", 0666, aa_sfs_entry.dentry,
2462 NULL, &aa_fs_profile_load);
2413
2414 return res;
2415}
2416
2417static const struct inode_operations policy_link_iops = {
2418 .readlink = policy_readlink,
2419 .get_link = policy_get_link,
2420};

--- 27 unchanged lines hidden (view full) ---

2448
2449 /* Populate fs tree. */
2450 error = entry_create_dir(&aa_sfs_entry, NULL);
2451 if (error)
2452 goto error;
2453
2454 dent = securityfs_create_file(".load", 0666, aa_sfs_entry.dentry,
2455 NULL, &aa_fs_profile_load);
2463 if (IS_ERR(dent)) {
2464 error = PTR_ERR(dent);
2465 goto error;
2466 }
2456 if (IS_ERR(dent))
2457 goto dent_error;
2467 ns_subload(root_ns) = dent;
2468
2469 dent = securityfs_create_file(".replace", 0666, aa_sfs_entry.dentry,
2470 NULL, &aa_fs_profile_replace);
2458 ns_subload(root_ns) = dent;
2459
2460 dent = securityfs_create_file(".replace", 0666, aa_sfs_entry.dentry,
2461 NULL, &aa_fs_profile_replace);
2471 if (IS_ERR(dent)) {
2472 error = PTR_ERR(dent);
2473 goto error;
2474 }
2462 if (IS_ERR(dent))
2463 goto dent_error;
2475 ns_subreplace(root_ns) = dent;
2476
2477 dent = securityfs_create_file(".remove", 0666, aa_sfs_entry.dentry,
2478 NULL, &aa_fs_profile_remove);
2464 ns_subreplace(root_ns) = dent;
2465
2466 dent = securityfs_create_file(".remove", 0666, aa_sfs_entry.dentry,
2467 NULL, &aa_fs_profile_remove);
2479 if (IS_ERR(dent)) {
2480 error = PTR_ERR(dent);
2481 goto error;
2482 }
2468 if (IS_ERR(dent))
2469 goto dent_error;
2483 ns_subremove(root_ns) = dent;
2484
2485 dent = securityfs_create_file("revision", 0444, aa_sfs_entry.dentry,
2486 NULL, &aa_fs_ns_revision_fops);
2470 ns_subremove(root_ns) = dent;
2471
2472 dent = securityfs_create_file("revision", 0444, aa_sfs_entry.dentry,
2473 NULL, &aa_fs_ns_revision_fops);
2487 if (IS_ERR(dent)) {
2488 error = PTR_ERR(dent);
2489 goto error;
2490 }
2474 if (IS_ERR(dent))
2475 goto dent_error;
2491 ns_subrevision(root_ns) = dent;
2492
2493 /* policy tree referenced by magic policy symlink */
2494 mutex_lock_nested(&root_ns->lock, root_ns->level);
2495 error = __aafs_ns_mkdir(root_ns, aafs_mnt->mnt_root, ".policy",
2496 aafs_mnt->mnt_root);
2497 mutex_unlock(&root_ns->lock);
2498 if (error)
2499 goto error;
2500
2501 /* magic symlink similar to nsfs redirects based on task policy */
2502 dent = securityfs_create_symlink("policy", aa_sfs_entry.dentry,
2503 NULL, &policy_link_iops);
2476 ns_subrevision(root_ns) = dent;
2477
2478 /* policy tree referenced by magic policy symlink */
2479 mutex_lock_nested(&root_ns->lock, root_ns->level);
2480 error = __aafs_ns_mkdir(root_ns, aafs_mnt->mnt_root, ".policy",
2481 aafs_mnt->mnt_root);
2482 mutex_unlock(&root_ns->lock);
2483 if (error)
2484 goto error;
2485
2486 /* magic symlink similar to nsfs redirects based on task policy */
2487 dent = securityfs_create_symlink("policy", aa_sfs_entry.dentry,
2488 NULL, &policy_link_iops);
2504 if (IS_ERR(dent)) {
2505 error = PTR_ERR(dent);
2506 goto error;
2507 }
2489 if (IS_ERR(dent))
2490 goto dent_error;
2508
2509 error = aa_mk_null_file(aa_sfs_entry.dentry);
2510 if (error)
2511 goto error;
2512
2513 /* TODO: add default profile to apparmorfs */
2514
2515 /* Report that AppArmor fs is enabled */
2516 aa_info_message("AppArmor Filesystem Enabled");
2517 return 0;
2518
2491
2492 error = aa_mk_null_file(aa_sfs_entry.dentry);
2493 if (error)
2494 goto error;
2495
2496 /* TODO: add default profile to apparmorfs */
2497
2498 /* Report that AppArmor fs is enabled */
2499 aa_info_message("AppArmor Filesystem Enabled");
2500 return 0;
2501
2502dent_error:
2503 error = PTR_ERR(dent);
2519error:
2520 aa_destroy_aafs();
2521 AA_ERROR("Error creating AppArmor securityfs\n");
2522 return error;
2523}
2524
2525fs_initcall(aa_create_aafs);
2504error:
2505 aa_destroy_aafs();
2506 AA_ERROR("Error creating AppArmor securityfs\n");
2507 return error;
2508}
2509
2510fs_initcall(aa_create_aafs);