From 45ff74bd5a009ab8f9648531fa11fce55b9a67fd Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Tue, 26 Jun 2018 20:19:19 -0700
Subject: [PATCH 3/3] apparmor: fix use after free in sk_peer_label

BugLink: http://bugs.launchpad.net/bugs/1778646
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
 security/apparmor/lsm.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 7a6b1bd8e046..0d2925389947 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1125,9 +1125,10 @@ static struct aa_label *sk_peer_label(struct sock *sk)
 {
 	struct sock *peer_sk;
 	struct aa_sk_ctx *ctx = SK_CTX(sk);
+	struct aa_label *label = ERR_PTR(-ENOPROTOOPT);
 
 	if (ctx->peer)
-		return ctx->peer;
+		return aa_get_label(ctx->peer);
 
 	if (sk->sk_family != PF_UNIX)
 		return ERR_PTR(-ENOPROTOOPT);
@@ -1135,14 +1136,15 @@ static struct aa_label *sk_peer_label(struct sock *sk)
 	/* check for sockpair peering which does not go through
 	 * security_unix_stream_connect
 	 */
-	peer_sk = unix_peer(sk);
+	peer_sk = unix_peer_get(sk);
 	if (peer_sk) {
 		ctx = SK_CTX(peer_sk);
 		if (ctx->label)
-			return ctx->label;
+			label = aa_get_label(ctx->label);
+		sock_put(peer_sk);
 	}
 
-	return ERR_PTR(-ENOPROTOOPT);
+	return label;
 }
 
 /**
@@ -1186,6 +1188,7 @@ static int apparmor_socket_getpeersec_stream(struct socket *sock,
 
 	}
 
+	aa_put_label(peer);
 done:
 	end_current_label_crit_section(label);
 
-- 
2.14.1