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;
}