summary refs log tree commit diff
path: root/security
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-24 13:00:33 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-24 13:00:33 -0700
commit57bb8e37d71eac45b6ea9180698a9cc3db945e26 (patch)
treea0ec057a95a4e2b0356d959808c33fd966b3a80d /security
parentaa5b1054badb60191f6a09e7ef65beacf837c5d4 (diff)
parentc037bd615885f1d9d3bdb48531bace79fae1505d (diff)
downloadlinux-57bb8e37d71eac45b6ea9180698a9cc3db945e26.tar.gz
Merge tag 'apparmor-pr-2018-08-23' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor
Pull apparmor updates from John Johansen:
 "There is nothing major this time just four bug fixes and a patch to
  remove some dead code:

  Cleanups:
   - remove no-op permission check in policy_unpack

  Bug fixes:
   - fix an error code in __aa_create_ns()
   - fix failure to audit context info in build_change_hat
   - check buffer bounds when mapping permissions mask
   - fully initialize aa_perms struct when answering userspace query"

* tag 'apparmor-pr-2018-08-23' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor:
  apparmor: remove no-op permission check in policy_unpack
  apparmor: fix an error code in __aa_create_ns()
  apparmor: Fix failure to audit context info in build_change_hat
  apparmor: Fully initialize aa_perms struct when answering userspace query
  apparmor: Check buffer bounds when mapping permissions mask
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/apparmorfs.c5
-rw-r--r--security/apparmor/domain.c2
-rw-r--r--security/apparmor/file.c3
-rw-r--r--security/apparmor/include/perms.h3
-rw-r--r--security/apparmor/lib.c17
-rw-r--r--security/apparmor/policy_ns.c2
-rw-r--r--security/apparmor/policy_unpack.c32
7 files changed, 20 insertions, 44 deletions
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 949dd8a48164..e09fe4d7307c 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -603,7 +603,7 @@ static const struct file_operations aa_fs_ns_revision_fops = {
 static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
 			     const char *match_str, size_t match_len)
 {
-	struct aa_perms tmp;
+	struct aa_perms tmp = { };
 	struct aa_dfa *dfa;
 	unsigned int state = 0;
 
@@ -613,7 +613,6 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
 		dfa = profile->file.dfa;
 		state = aa_dfa_match_len(dfa, profile->file.start,
 					 match_str + 1, match_len - 1);
-		tmp = nullperms;
 		if (state) {
 			struct path_cond cond = { };
 
@@ -627,8 +626,6 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
 					 match_str, match_len);
 		if (state)
 			aa_compute_perms(dfa, state, &tmp);
-		else
-			tmp = nullperms;
 	}
 	aa_apply_modes_to_perms(profile, &tmp);
 	aa_perms_accum_raw(perms, &tmp);
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 098d546d8253..08c88de0ffda 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -1036,7 +1036,7 @@ static struct aa_label *build_change_hat(struct aa_profile *profile,
 audit:
 	aa_audit_file(profile, &nullperms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT,
 		      name, hat ? hat->base.hname : NULL,
-		      hat ? &hat->label : NULL, GLOBAL_ROOT_UID, NULL,
+		      hat ? &hat->label : NULL, GLOBAL_ROOT_UID, info,
 		      error);
 	if (!hat || (error && error != -ENOENT))
 		return ERR_PTR(error);
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 224b2fef93ca..4285943f7260 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -47,7 +47,8 @@ static void audit_file_mask(struct audit_buffer *ab, u32 mask)
 {
 	char str[10];
 
-	aa_perm_mask_to_str(str, aa_file_perm_chrs, map_mask_to_chr_mask(mask));
+	aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
+			    map_mask_to_chr_mask(mask));
 	audit_log_string(ab, str);
 }
 
diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
index 38aa6247d00f..b94ec114d1a4 100644
--- a/security/apparmor/include/perms.h
+++ b/security/apparmor/include/perms.h
@@ -137,7 +137,8 @@ extern struct aa_perms allperms;
 	xcheck(fn_for_each((L1), (P), (FN1)), fn_for_each((L2), (P), (FN2)))
 
 
-void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask);
+void aa_perm_mask_to_str(char *str, size_t str_size, const char *chrs,
+			 u32 mask);
 void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names,
 			 u32 mask);
 void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index a7b3f681b80e..974affe50531 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -198,15 +198,24 @@ const char *aa_file_perm_names[] = {
 /**
  * aa_perm_mask_to_str - convert a perm mask to its short string
  * @str: character buffer to store string in (at least 10 characters)
+ * @str_size: size of the @str buffer
+ * @chrs: NUL-terminated character buffer of permission characters
  * @mask: permission mask to convert
  */
-void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask)
+void aa_perm_mask_to_str(char *str, size_t str_size, const char *chrs, u32 mask)
 {
 	unsigned int i, perm = 1;
+	size_t num_chrs = strlen(chrs);
+
+	for (i = 0; i < num_chrs; perm <<= 1, i++) {
+		if (mask & perm) {
+			/* Ensure that one byte is left for NUL-termination */
+			if (WARN_ON_ONCE(str_size <= 1))
+				break;
 
-	for (i = 0; i < 32; perm <<= 1, i++) {
-		if (mask & perm)
 			*str++ = chrs[i];
+			str_size--;
+		}
 	}
 	*str = '\0';
 }
@@ -236,7 +245,7 @@ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
 
 	audit_log_format(ab, "\"");
 	if ((mask & chrsmask) && chrs) {
-		aa_perm_mask_to_str(str, chrs, mask & chrsmask);
+		aa_perm_mask_to_str(str, sizeof(str), chrs, mask & chrsmask);
 		mask &= ~chrsmask;
 		audit_log_format(ab, "%s", str);
 		if (mask & namesmask)
diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
index b0f9dc3f765a..1a7cec5d9cac 100644
--- a/security/apparmor/policy_ns.c
+++ b/security/apparmor/policy_ns.c
@@ -255,7 +255,7 @@ static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
 
 	ns = alloc_ns(parent->base.hname, name);
 	if (!ns)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 	ns->level = parent->level + 1;
 	mutex_lock_nested(&ns->lock, ns->level);
 	error = __aafs_ns_mkdir(ns, ns_subns_dir(parent), name, dir);
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 0e566a01d217..21cb384d712a 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -389,32 +389,6 @@ static int unpack_strdup(struct aa_ext *e, char **string, const char *name)
 	return res;
 }
 
-#define DFA_VALID_PERM_MASK		0xffffffff
-#define DFA_VALID_PERM2_MASK		0xffffffff
-
-/**
- * verify_accept - verify the accept tables of a dfa
- * @dfa: dfa to verify accept tables of (NOT NULL)
- * @flags: flags governing dfa
- *
- * Returns: 1 if valid accept tables else 0 if error
- */
-static bool verify_accept(struct aa_dfa *dfa, int flags)
-{
-	int i;
-
-	/* verify accept permissions */
-	for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
-		int mode = ACCEPT_TABLE(dfa)[i];
-
-		if (mode & ~DFA_VALID_PERM_MASK)
-			return 0;
-
-		if (ACCEPT_TABLE2(dfa)[i] & ~DFA_VALID_PERM2_MASK)
-			return 0;
-	}
-	return 1;
-}
 
 /**
  * unpack_dfa - unpack a file rule dfa
@@ -445,15 +419,9 @@ static struct aa_dfa *unpack_dfa(struct aa_ext *e)
 		if (IS_ERR(dfa))
 			return dfa;
 
-		if (!verify_accept(dfa, flags))
-			goto fail;
 	}
 
 	return dfa;
-
-fail:
-	aa_put_dfa(dfa);
-	return ERR_PTR(-EPROTO);
 }
 
 /**