[pve-devel] [PATCH kernel] AppArmor: add temporary socket mediation fix

Wolfgang Bumiller w.bumiller at proxmox.com
Fri Dec 18 12:21:51 CET 2015


Fixes launchpad #1446906 (failed mediation of a socket
that is being shutdown.)

Fixes the apparmor bug manifesting with postfix' mailq
command.
---
 Makefile                        |   1 +
 apparmor-socket-mediation.patch | 111 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 112 insertions(+)
 create mode 100644 apparmor-socket-mediation.patch

diff --git a/Makefile b/Makefile
index 5dc101d..02a9f26 100644
--- a/Makefile
+++ b/Makefile
@@ -238,6 +238,7 @@ ${KERNEL_SRC}/README ${KERNEL_CFG_ORG}: ${KERNELSRCTAR}
 	cd ${KERNEL_SRC}; patch -p1 <../kvmstealtime.patch
 	cd ${KERNEL_SRC}; patch -p1 <../kvm-x86-obey-KVM_X86_QUIRK_CD_NW_CLEARED-in-kvm_set_cr0.patch
 	cd ${KERNEL_SRC}; patch -p1 <../KVM-svm-unconditionally-intercept-DB.patch
+	cd ${KERNEL_SRC}; patch -p1 <../apparmor-socket-mediation.patch
 	sed -i ${KERNEL_SRC}/Makefile -e 's/^EXTRAVERSION.*$$/EXTRAVERSION=${EXTRAVERSION}/'
 	touch $@
 
diff --git a/apparmor-socket-mediation.patch b/apparmor-socket-mediation.patch
new file mode 100644
index 0000000..ef8e44f
--- /dev/null
+++ b/apparmor-socket-mediation.patch
@@ -0,0 +1,111 @@
+From f93d775c9342c4cf6d19b75ce81654cc3c87fb8b Mon Sep 17 00:00:00 2001
+From: John Johansen <john.johansen at canonical.com>
+Date: Tue, 15 Dec 2015 05:33:54 -0800
+Subject: [PATCH] apparmor: fix for failed mediation of socket that is being
+ shutdown
+
+BugLink: http://bugs.launchpad.net/bugs/1446906
+
+This is a horrendous HACK, that is a temporary fix until typesplitting
+can land.
+
+Store off the path reference on connection to make up for the path
+being wiped out on socket shutdown.
+
+Signed-off-by: John Johansen <john.johansen at canonical.com>
+---
+ security/apparmor/af_unix.c     |  4 ++++
+ security/apparmor/include/net.h |  2 ++
+ security/apparmor/lsm.c         | 20 ++++++++++++++++++++
+ 3 files changed, 26 insertions(+)
+
+diff --git a/security/apparmor/af_unix.c b/security/apparmor/af_unix.c
+index 5783bbb..5115ee9 100644
+--- a/security/apparmor/af_unix.c
++++ b/security/apparmor/af_unix.c
+@@ -40,6 +40,10 @@ static inline int unix_fs_perm(int op, u32 mask, struct aa_label *label,
+ 		/* socket path has been cleared because it is being shutdown
+ 		 * can only fall back to original sun_path request
+ 		 */
++		struct aa_sk_cxt *cxt = SK_CXT(&u->sk);
++		if (cxt->path.dentry)
++			return aa_path_perm(op, label, &cxt->path, flags, mask,
++					    &cond);
+ 		return fn_for_each_confined(label, profile,
+ 			((flags | profile->path_flags) & PATH_MEDIATE_DELETED) ?
+ 				__aa_path_perm(op, profile,
+diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
+index 4a5fae5..1aedbf6 100644
+--- a/security/apparmor/include/net.h
++++ b/security/apparmor/include/net.h
+@@ -16,6 +16,7 @@
+ #define __AA_NET_H
+ 
+ #include <net/sock.h>
++#include <linux/path.h>
+ 
+ #include "apparmorfs.h"
+ #include "label.h"
+@@ -52,6 +53,7 @@
+ struct aa_sk_cxt {
+ 	struct aa_label *label;
+ 	struct aa_label *peer;
++	struct path path;
+ };
+ 
+ #define SK_CXT(X) (X)->sk_security
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index bf8196a..387edb8 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -767,6 +767,7 @@ static void apparmor_sk_free_security(struct sock *sk)
+ 	SK_CXT(sk) = NULL;
+ 	aa_put_label(cxt->label);
+ 	aa_put_label(cxt->peer);
++	path_put(&cxt->path);
+ 	kfree(cxt);
+ }
+ 
+@@ -781,6 +782,17 @@ static void apparmor_sk_clone_security(const struct sock *sk,
+ 
+ 	new->label = aa_get_label(cxt->label);
+ 	new->peer = aa_get_label(cxt->peer);
++	new->path = cxt->path;
++	path_get(&new->path);
++}
++
++static struct path *UNIX_FS_CONN_PATH(struct sock *sk, struct sock *newsk)
++{
++	if (sk->sk_family == PF_UNIX && UNIX_FS(sk))
++		return &unix_sk(sk)->path;
++	else if (sk->sk_family == PF_UNIX && UNIX_FS(newsk))
++		return &unix_sk(newsk)->path;
++	return NULL;
+ }
+ 
+ /**
+@@ -795,6 +807,7 @@ static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk,
+ 	struct aa_sk_cxt *peer_cxt = SK_CXT(peer_sk);
+ 	struct aa_sk_cxt *new_cxt = SK_CXT(newsk);
+ 	struct aa_label *label;
++	struct path *path;
+ 	int error;
+ 
+ 	label = aa_begin_current_label(NO_UPDATE);
+@@ -830,6 +843,13 @@ static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk,
+ 	new_cxt->peer = aa_get_label(sk_cxt->label);
+ 	sk_cxt->peer = aa_get_label(peer_cxt->label);
+ 
++	path = UNIX_FS_CONN_PATH(sk, peer_sk);
++	if (path) {
++		new_cxt->path = *path;
++		sk_cxt->path = *path;
++		path_get(path);
++		path_get(path);
++	}
+ 	return 0;
+ }
+ 
+-- 
+2.1.4
+
-- 
2.1.4




More information about the pve-devel mailing list