Blob Blame History Raw
From: Goldwyn Rodrigues <rgoldwyn@suse.com>
Subject: [PATCH] Check all profiles attached to the label
Patch-mainline: Never, depends on apparmor-basic-networking-rules
References: bsc#1085996

This one fixes patches.suse/0001-AppArmor-basic-networking-rules.patch

While porting apparmor net patch to the newer kernel, I missed on
iterating over the profiles attached to the labels and used
labels_profile(). This missed checking the rest of the profiles attached
to the label.

While we are at it, use wrapper function begin_current_label_crit_section()
as opposed to the __begin_current_label_crit_section().

Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>

diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
index 6710a5369380..580232f20047 100644
--- a/security/apparmor/include/net.h
+++ b/security/apparmor/include/net.h
@@ -32,7 +32,7 @@ struct aa_net {
 
 extern struct aa_sfs_entry aa_sfs_entry_network[];
 
-int aa_net_perm(const char *op, struct aa_profile *profile, u16 family,
+int aa_label_net_perm(struct aa_label *label, const char *op, u16 family,
 		       int type, int protocol, struct sock *sk);
 int aa_revalidate_sk(const char *op, struct sock *sk);
 
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index e62b06241476..0007fb2eed29 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -745,11 +745,11 @@ static int apparmor_socket_create(int family, int type, int protocol, int kern)
 	if (kern)
 		return 0;
 
-	label = __begin_current_label_crit_section();
+	label = begin_current_label_crit_section();
 	if (!unconfined(label))
-		error = aa_net_perm(OP_CREATE, labels_profile(label),
+		error = aa_label_net_perm(label, OP_CREATE,
 				family, type, protocol, NULL);
-	__end_current_label_crit_section(label);
+	end_current_label_crit_section(label);
 	return error;
 }
 
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
index 48e66a61b9c6..95d6e3b9c71d 100644
--- a/security/apparmor/net.c
+++ b/security/apparmor/net.c
@@ -114,7 +114,7 @@ static int audit_net(struct aa_profile *profile, const char *op,
  *
  * Returns: %0 else error if permission denied
  */
-int aa_net_perm(const char *op, struct aa_profile *profile, u16 family,
+static int aa_net_perm(const char *op, struct aa_profile *profile, u16 family,
 		int type, int protocol, struct sock *sk)
 {
 	u16 family_mask;
@@ -137,6 +137,18 @@ int aa_net_perm(const char *op, struct aa_profile *profile, u16 family,
 	return audit_net(profile, op, family, type, protocol, sk, error);
 }
 
+int aa_label_net_perm(struct aa_label *label, const char *op, u16 family,
+		int type, int protocol, struct sock *sk)
+{
+	struct aa_profile *profile;
+
+	if (unconfined(label))
+		return 0;
+
+	return fn_for_each_confined(label, profile,
+			aa_net_perm(op, profile, family, type, protocol, sk));
+}
+
 /**
  * aa_revalidate_sk - Revalidate access to a sock
  * @op: operation being checked
@@ -155,11 +167,10 @@ int aa_revalidate_sk(const char *op, struct sock *sk)
 	if (in_interrupt())
 		return 0;
 
-	label = __begin_current_label_crit_section();
-	if (!unconfined(label))
-		error = aa_net_perm(op, labels_profile(label), sk->sk_family,
-				sk->sk_type, sk->sk_protocol, sk);
-	__end_current_label_crit_section(label);
+	label = begin_current_label_crit_section();
+	error = aa_label_net_perm(label, op, sk->sk_family, sk->sk_type,
+			sk->sk_protocol, sk);
+	end_current_label_crit_section(label);
 
 	return error;
 }