]> git.proxmox.com Git - pve-kernel-jessie.git/commitdiff
AppArmor: add temporary socket mediation fix
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Fri, 18 Dec 2015 11:21:51 +0000 (12:21 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Fri, 18 Dec 2015 11:38:17 +0000 (12:38 +0100)
Fixes launchpad #1446906 (failed mediation of a socket
that is being shutdown.)

Fixes the apparmor bug manifesting with postfix' mailq
command.

Makefile
apparmor-socket-mediation.patch [new file with mode: 0644]

index 5dc101de6dea6a8afb54c6464723f4fcc1bb3512..02a9f26544db80b29cd32394c9253bbd7ffeb48d 100644 (file)
--- 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 (file)
index 0000000..ef8e44f
--- /dev/null
@@ -0,0 +1,111 @@
+From f93d775c9342c4cf6d19b75ce81654cc3c87fb8b Mon Sep 17 00:00:00 2001
+From: John Johansen <john.johansen@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@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
+