diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-05 21:26:35 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-05 21:26:35 +0300 |
commit | e24dd9ee5399747b71c1d982a484fc7601795f31 (patch) | |
tree | 14fcec8728916092a9f6dbeb0f2b8d5c5a4e5c9a /security/apparmor/include/policy.h | |
parent | 7391786a64dcfe9c609a1f8e2204c1abf42ded23 (diff) | |
parent | c4758fa59285fe4dbfeab4364a6957936d040fbf (diff) | |
download | linux-e24dd9ee5399747b71c1d982a484fc7601795f31.tar.xz |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security layer updates from James Morris:
- a major update for AppArmor. From JJ:
* several bug fixes and cleanups
* the patch to add symlink support to securityfs that was floated
on the list earlier and the apparmorfs changes that make use of
securityfs symlinks
* it introduces the domain labeling base code that Ubuntu has been
carrying for several years, with several cleanups applied. And it
converts the current mediation over to using the domain labeling
base, which brings domain stacking support with it. This finally
will bring the base upstream code in line with Ubuntu and provide
a base to upstream the new feature work that Ubuntu carries.
* This does _not_ contain any of the newer apparmor mediation
features/controls (mount, signals, network, keys, ...) that
Ubuntu is currently carrying, all of which will be RFC'd on top
of this.
- Notable also is the Infiniband work in SELinux, and the new file:map
permission. From Paul:
"While we're down to 21 patches for v4.13 (it was 31 for v4.12),
the diffstat jumps up tremendously with over 2k of line changes.
Almost all of these changes are the SELinux/IB work done by
Daniel Jurgens; some other noteworthy changes include a NFS v4.2
labeling fix, a new file:map permission, and reporting of policy
capabilities on policy load"
There's also now genfscon labeling support for tracefs, which was
lost in v4.1 with the separation from debugfs.
- Smack incorporates a safer socket check in file_receive, and adds a
cap_capable call in privilege check.
- TPM as usual has a bunch of fixes and enhancements.
- Multiple calls to security_add_hooks() can now be made for the same
LSM, to allow LSMs to have hook declarations across multiple files.
- IMA now supports different "ima_appraise=" modes (eg. log, fix) from
the boot command line.
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (126 commits)
apparmor: put back designators in struct initialisers
seccomp: Switch from atomic_t to recount_t
seccomp: Adjust selftests to avoid double-join
seccomp: Clean up core dump logic
IMA: update IMA policy documentation to include pcr= option
ima: Log the same audit cause whenever a file has no signature
ima: Simplify policy_func_show.
integrity: Small code improvements
ima: fix get_binary_runtime_size()
ima: use ima_parse_buf() to parse template data
ima: use ima_parse_buf() to parse measurements headers
ima: introduce ima_parse_buf()
ima: Add cgroups2 to the defaults list
ima: use memdup_user_nul
ima: fix up #endif comments
IMA: Correct Kconfig dependencies for hash selection
ima: define is_ima_appraise_enabled()
ima: define Kconfig IMA_APPRAISE_BOOTPARAM option
ima: define a set of appraisal rules requiring file signatures
ima: extend the "ima_policy" boot command line to support multiple policies
...
Diffstat (limited to 'security/apparmor/include/policy.h')
-rw-r--r-- | security/apparmor/include/policy.h | 131 |
1 files changed, 51 insertions, 80 deletions
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index 67bc96afe541..17fe41a9cac3 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h @@ -29,6 +29,8 @@ #include "domain.h" #include "file.h" #include "lib.h" +#include "label.h" +#include "perms.h" #include "resource.h" @@ -47,9 +49,9 @@ extern const char *const aa_profile_mode_names[]; #define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL) -#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT) +#define PROFILE_IS_HAT(_profile) ((_profile)->label.flags & FLAG_HAT) -#define profile_is_stale(_profile) ((_profile)->flags & PFLAG_STALE) +#define profile_is_stale(_profile) (label_is_stale(&(_profile)->label)) #define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2) @@ -66,22 +68,6 @@ enum profile_mode { APPARMOR_UNCONFINED, /* profile set to unconfined */ }; -enum profile_flags { - PFLAG_HAT = 1, /* profile is a hat */ - PFLAG_NULL = 4, /* profile is null learning profile */ - PFLAG_IX_ON_NAME_ERROR = 8, /* fallback to ix on name lookup fail */ - PFLAG_IMMUTABLE = 0x10, /* don't allow changes/replacement */ - PFLAG_USER_DEFINED = 0x20, /* user based profile - lower privs */ - PFLAG_NO_LIST_REF = 0x40, /* list doesn't keep profile ref */ - PFLAG_OLD_NULL_TRANS = 0x100, /* use // as the null transition */ - PFLAG_STALE = 0x200, /* profile replaced/removed */ - PFLAG_NS_COUNT = 0x400, /* carries NS ref count */ - - /* These flags must correspond with PATH_flags */ - PFLAG_MEDIATE_DELETED = 0x10000, /* mediate instead delegate deleted */ -}; - -struct aa_profile; /* struct aa_policydb - match engine for a policy * dfa: dfa pattern match @@ -94,11 +80,6 @@ struct aa_policydb { }; -struct aa_proxy { - struct kref count; - struct aa_profile __rcu *profile; -}; - /* struct aa_data - generic data structure * key: name for retrieving this data * size: size of data in bytes @@ -115,19 +96,17 @@ struct aa_data { /* struct aa_profile - basic confinement data * @base - base components of the profile (name, refcount, lists, lock ...) - * @count: reference count of the obj - * @rcu: rcu head used when removing from @list + * @label - label this profile is an extension of * @parent: parent of profile * @ns: namespace the profile is in - * @proxy: is set to the profile that replaced this profile * @rename: optional profile name that this profile renamed * @attach: human readable attachment string * @xmatch: optional extended matching for unconfined executables names * @xmatch_len: xmatch prefix len, used to determine xmatch priority * @audit: the auditing mode of the profile * @mode: the enforcement mode of the profile - * @flags: flags controlling profile behavior * @path_flags: flags controlling path generation behavior + * @disconnected: what to prepend if attach_disconnected is specified * @size: the memory consumed by this profiles rules * @policy: general match rules governing policy * @file: The set of rules governing basic file access and domain transitions @@ -143,8 +122,6 @@ struct aa_data { * used to determine profile attachment against unconfined tasks. All other * attachments are determined by profile X transition rules. * - * The @proxy struct is write protected by the profile lock. - * * Profiles have a hierarchy where hats and children profiles keep * a reference to their parent. * @@ -154,12 +131,9 @@ struct aa_data { */ struct aa_profile { struct aa_policy base; - struct kref count; - struct rcu_head rcu; struct aa_profile __rcu *parent; struct aa_ns *ns; - struct aa_proxy *proxy; const char *rename; const char *attach; @@ -167,8 +141,8 @@ struct aa_profile { int xmatch_len; enum audit_mode audit; long mode; - long flags; u32 path_flags; + const char *disconnected; int size; struct aa_policydb policy; @@ -181,17 +155,24 @@ struct aa_profile { char *dirname; struct dentry *dents[AAFS_PROF_SIZEOF]; struct rhashtable *data; + struct aa_label label; }; extern enum profile_mode aa_g_profile_mode; -void __aa_update_proxy(struct aa_profile *orig, struct aa_profile *new); +#define AA_MAY_LOAD_POLICY AA_MAY_APPEND +#define AA_MAY_REPLACE_POLICY AA_MAY_WRITE +#define AA_MAY_REMOVE_POLICY AA_MAY_DELETE + +#define profiles_ns(P) ((P)->ns) +#define name_is_shared(A, B) ((A)->hname && (A)->hname == (B)->hname) void aa_add_profile(struct aa_policy *common, struct aa_profile *profile); void aa_free_proxy_kref(struct kref *kref); -struct aa_profile *aa_alloc_profile(const char *name, gfp_t gfp); +struct aa_profile *aa_alloc_profile(const char *name, struct aa_proxy *proxy, + gfp_t gfp); struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat, const char *base, gfp_t gfp); void aa_free_profile(struct aa_profile *profile); @@ -200,21 +181,44 @@ struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name); struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname, size_t n); struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *name); -struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base, +struct aa_profile *aa_fqlookupn_profile(struct aa_label *base, const char *fqname, size_t n); struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name); -ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile, - bool noreplace, struct aa_loaddata *udata); -ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *profile, - char *name, size_t size); +ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_label *label, + u32 mask, struct aa_loaddata *udata); +ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_label *label, + char *name, size_t size); void __aa_profile_list_release(struct list_head *head); #define PROF_ADD 1 #define PROF_REPLACE 0 -#define unconfined(X) ((X)->mode == APPARMOR_UNCONFINED) +#define profile_unconfined(X) ((X)->mode == APPARMOR_UNCONFINED) + +/** + * aa_get_newest_profile - simple wrapper fn to wrap the label version + * @p: profile (NOT NULL) + * + * Returns refcount to newest version of the profile (maybe @p) + * + * Requires: @p must be held with a valid refcount + */ +static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p) +{ + return labels_profile(aa_get_newest_label(&p->label)); +} +#define PROFILE_MEDIATES(P, T) ((P)->policy.start[(T)]) +/* safe version of POLICY_MEDIATES for full range input */ +static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile, + unsigned char class) +{ + if (profile->policy.dfa) + return aa_dfa_match_len(profile->policy.dfa, + profile->policy.start[0], &class, 1); + return 0; +} /** * aa_get_profile - increment refcount on profile @p @@ -226,7 +230,7 @@ void __aa_profile_list_release(struct list_head *head); static inline struct aa_profile *aa_get_profile(struct aa_profile *p) { if (p) - kref_get(&(p->count)); + kref_get(&(p->label.count)); return p; } @@ -240,7 +244,7 @@ static inline struct aa_profile *aa_get_profile(struct aa_profile *p) */ static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p) { - if (p && kref_get_unless_zero(&p->count)) + if (p && kref_get_unless_zero(&p->label.count)) return p; return NULL; @@ -260,53 +264,20 @@ static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p) rcu_read_lock(); do { c = rcu_dereference(*p); - } while (c && !kref_get_unless_zero(&c->count)); + } while (c && !kref_get_unless_zero(&c->label.count)); rcu_read_unlock(); return c; } /** - * aa_get_newest_profile - find the newest version of @profile - * @profile: the profile to check for newer versions of - * - * Returns: refcounted newest version of @profile taking into account - * replacement, renames and removals - * return @profile. - */ -static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p) -{ - if (!p) - return NULL; - - if (profile_is_stale(p)) - return aa_get_profile_rcu(&p->proxy->profile); - - return aa_get_profile(p); -} - -/** * aa_put_profile - decrement refcount on profile @p * @p: profile (MAYBE NULL) */ static inline void aa_put_profile(struct aa_profile *p) { if (p) - kref_put(&p->count, aa_free_profile_kref); -} - -static inline struct aa_proxy *aa_get_proxy(struct aa_proxy *p) -{ - if (p) - kref_get(&(p->count)); - - return p; -} - -static inline void aa_put_proxy(struct aa_proxy *p) -{ - if (p) - kref_put(&p->count, aa_free_proxy_kref); + kref_put(&p->label.count, aa_label_kref); } static inline int AUDIT_MODE(struct aa_profile *profile) @@ -319,7 +290,7 @@ static inline int AUDIT_MODE(struct aa_profile *profile) bool policy_view_capable(struct aa_ns *ns); bool policy_admin_capable(struct aa_ns *ns); -int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns, - const char *op); +int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns, + u32 mask); #endif /* __AA_POLICY_H */ |