summaryrefslogtreecommitdiff
path: root/security/apparmor
diff options
context:
space:
mode:
Diffstat (limited to 'security/apparmor')
-rw-r--r--security/apparmor/.gitignore1
-rw-r--r--security/apparmor/Makefile4
-rw-r--r--security/apparmor/domain.c4
-rw-r--r--security/apparmor/file.c12
-rw-r--r--security/apparmor/include/audit.h2
-rw-r--r--security/apparmor/include/file.h4
-rw-r--r--security/apparmor/lsm.c2
-rw-r--r--security/apparmor/policy.c24
8 files changed, 38 insertions, 15 deletions
diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore
index 4d995aeaebc0..9cdec70d72b8 100644
--- a/security/apparmor/.gitignore
+++ b/security/apparmor/.gitignore
@@ -1,6 +1,5 @@
#
# Generated include files
#
-af_names.h
capability_names.h
rlim_names.h
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index 806bd19af7f2..5706b74c857f 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -57,9 +57,9 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
$(obj)/capability.o : $(obj)/capability_names.h
$(obj)/resource.o : $(obj)/rlim_names.h
-$(obj)/capability_names.h : $(srctree)/include/linux/capability.h \
+$(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
$(src)/Makefile
$(call cmd,make-caps)
-$(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h \
+$(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \
$(src)/Makefile
$(call cmd,make-rlim)
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index b81ea10a17a3..60f0c76a27d3 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -721,7 +721,7 @@ audit:
if (!permtest)
error = aa_audit_file(profile, &perms, GFP_KERNEL,
OP_CHANGE_HAT, AA_MAY_CHANGEHAT, NULL,
- target, 0, info, error);
+ target, GLOBAL_ROOT_UID, info, error);
out:
aa_put_profile(hat);
@@ -848,7 +848,7 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
audit:
if (!permtest)
error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request,
- name, hname, 0, info, error);
+ name, hname, GLOBAL_ROOT_UID, info, error);
aa_put_namespace(ns);
aa_put_profile(target);
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index cf19d4093ca4..cd21ec5b90af 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -65,7 +65,7 @@ static void audit_file_mask(struct audit_buffer *ab, u32 mask)
static void file_audit_cb(struct audit_buffer *ab, void *va)
{
struct common_audit_data *sa = va;
- uid_t fsuid = current_fsuid();
+ kuid_t fsuid = current_fsuid();
if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) {
audit_log_format(ab, " requested_mask=");
@@ -76,8 +76,10 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
audit_file_mask(ab, sa->aad->fs.denied);
}
if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) {
- audit_log_format(ab, " fsuid=%d", fsuid);
- audit_log_format(ab, " ouid=%d", sa->aad->fs.ouid);
+ audit_log_format(ab, " fsuid=%d",
+ from_kuid(&init_user_ns, fsuid));
+ audit_log_format(ab, " ouid=%d",
+ from_kuid(&init_user_ns, sa->aad->fs.ouid));
}
if (sa->aad->fs.target) {
@@ -103,7 +105,7 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
*/
int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
gfp_t gfp, int op, u32 request, const char *name,
- const char *target, uid_t ouid, const char *info, int error)
+ const char *target, kuid_t ouid, const char *info, int error)
{
int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa;
@@ -201,7 +203,7 @@ static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state,
*/
perms.kill = 0;
- if (current_fsuid() == cond->uid) {
+ if (uid_eq(current_fsuid(), cond->uid)) {
perms.allow = map_old_perms(dfa_user_allow(dfa, state));
perms.audit = map_old_perms(dfa_user_audit(dfa, state));
perms.quiet = map_old_perms(dfa_user_quiet(dfa, state));
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index 4b7e18951aea..69d8cae634e7 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -125,7 +125,7 @@ struct apparmor_audit_data {
const char *target;
u32 request;
u32 denied;
- uid_t ouid;
+ kuid_t ouid;
} fs;
};
};
diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
index f98fd4701d80..967b2deda376 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -71,7 +71,7 @@ struct path;
/* need to make conditional which ones are being set */
struct path_cond {
- uid_t uid;
+ kuid_t uid;
umode_t mode;
};
@@ -146,7 +146,7 @@ static inline u16 dfa_map_xindex(u16 mask)
int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
gfp_t gfp, int op, u32 request, const char *name,
- const char *target, uid_t ouid, const char *info, int error);
+ const char *target, kuid_t ouid, const char *info, int error);
/**
* struct aa_file_rules - components used for file rule permissions
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 8ea39aabe948..8c2a7f6b35e2 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -352,7 +352,7 @@ static int apparmor_path_chmod(struct path *path, umode_t mode)
return common_perm_mnt_dentry(OP_CHMOD, path->mnt, path->dentry, AA_MAY_CHMOD);
}
-static int apparmor_path_chown(struct path *path, uid_t uid, gid_t gid)
+static int apparmor_path_chown(struct path *path, kuid_t uid, kgid_t gid)
{
struct path_cond cond = { path->dentry->d_inode->i_uid,
path->dentry->d_inode->i_mode
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index cf5fd220309b..813200384d97 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -724,6 +724,8 @@ fail:
*/
static void free_profile(struct aa_profile *profile)
{
+ struct aa_profile *p;
+
AA_DEBUG("%s(%p)\n", __func__, profile);
if (!profile)
@@ -751,7 +753,27 @@ static void free_profile(struct aa_profile *profile)
aa_put_dfa(profile->xmatch);
aa_put_dfa(profile->policy.dfa);
- aa_put_profile(profile->replacedby);
+ /* put the profile reference for replacedby, but not via
+ * put_profile(kref_put).
+ * replacedby can form a long chain that can result in cascading
+ * frees that blows the stack because kref_put makes a nested fn
+ * call (it looks like recursion, with free_profile calling
+ * free_profile) for each profile in the chain lp#1056078.
+ */
+ for (p = profile->replacedby; p; ) {
+ if (atomic_dec_and_test(&p->base.count.refcount)) {
+ /* no more refs on p, grab its replacedby */
+ struct aa_profile *next = p->replacedby;
+ /* break the chain */
+ p->replacedby = NULL;
+ /* now free p, chain is broken */
+ free_profile(p);
+
+ /* follow up with next profile in the chain */
+ p = next;
+ } else
+ break;
+ }
kzfree(profile);
}