[linux] 01/01: sunrpc: fix refcounting problems with auth_gss messages

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Tue Feb 28 11:20:02 UTC 2017


This is an automated email from the git hooks/post-receive script.

carnil pushed a commit to branch jessie
in repository linux.

commit da6af8dc1b6eddb4e3ec6ef2fd482491cc70bcef
Author: Salvatore Bonaccorso <carnil at debian.org>
Date:   Tue Feb 28 10:59:04 2017 +0100

    sunrpc: fix refcounting problems with auth_gss messages
    
    Thanks: Raphael Geissert <geissert at debian.org>
    Closes: #852708
---
 debian/changelog                                   |  5 ++
 ...refcounting-problems-with-auth_gss-messag.patch | 85 ++++++++++++++++++++++
 debian/patches/series                              |  1 +
 3 files changed, 91 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index ff22c3b..0d5d8dc 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,7 +1,12 @@
 linux (3.16.39-2) UNRELEASED; urgency=medium
 
+  [ Ben Hutchings ]
   * locking/mutex: Don't assume TASK_RUNNING (Closes: #841171)
 
+  [ Salvatore Bonaccorso ]
+  * sunrpc: fix refcounting problems with auth_gss messages.
+    Thanks to Raphael Geissert <geissert at debian.org> (Closes: #852708)
+
  -- Ben Hutchings <ben at decadent.org.uk>  Sun, 01 Jan 2017 22:44:31 +0000
 
 linux (3.16.39-1+deb8u1) jessie-security; urgency=high
diff --git a/debian/patches/bugfix/all/SUNRPC-fix-refcounting-problems-with-auth_gss-messag.patch b/debian/patches/bugfix/all/SUNRPC-fix-refcounting-problems-with-auth_gss-messag.patch
new file mode 100644
index 0000000..72df615
--- /dev/null
+++ b/debian/patches/bugfix/all/SUNRPC-fix-refcounting-problems-with-auth_gss-messag.patch
@@ -0,0 +1,85 @@
+From: NeilBrown <neilb at suse.com>
+Date: Mon, 5 Dec 2016 15:10:11 +1100
+Subject: SUNRPC: fix refcounting problems with auth_gss messages.
+Origin: https://git.kernel.org/linus/1cded9d2974fe4fe339fc0ccd6638b80d465ab2c
+Bug-Debian: https://bugs.debian.org/852708
+
+There are two problems with refcounting of auth_gss messages.
+
+First, the reference on the pipe->pipe list (taken by a call
+to rpc_queue_upcall()) is not counted.  It seems to be
+assumed that a message in pipe->pipe will always also be in
+pipe->in_downcall, where it is correctly reference counted.
+
+However there is no guaranty of this.  I have a report of a
+NULL dereferences in rpc_pipe_read() which suggests a msg
+that has been freed is still on the pipe->pipe list.
+
+One way I imagine this might happen is:
+- message is queued for uid=U and auth->service=S1
+- rpc.gssd reads this message and starts processing.
+  This removes the message from pipe->pipe
+- message is queued for uid=U and auth->service=S2
+- rpc.gssd replies to the first message. gss_pipe_downcall()
+  calls __gss_find_upcall(pipe, U, NULL) and it finds the
+  *second* message, as new messages are placed at the head
+  of ->in_downcall, and the service type is not checked.
+- This second message is removed from ->in_downcall and freed
+  by gss_release_msg() (even though it is still on pipe->pipe)
+- rpc.gssd tries to read another message, and dereferences a pointer
+  to this message that has just been freed.
+
+I fix this by incrementing the reference count before calling
+rpc_queue_upcall(), and decrementing it if that fails, or normally in
+gss_pipe_destroy_msg().
+
+It seems strange that the reply doesn't target the message more
+precisely, but I don't know all the details.  In any case, I think the
+reference counting irregularity became a measureable bug when the
+extra arg was added to __gss_find_upcall(), hence the Fixes: line
+below.
+
+The second problem is that if rpc_queue_upcall() fails, the new
+message is not freed. gss_alloc_msg() set the ->count to 1,
+gss_add_msg() increments this to 2, gss_unhash_msg() decrements to 1,
+then the pointer is discarded so the memory never gets freed.
+
+Fixes: 9130b8dbc6ac ("SUNRPC: allow for upcalls for same uid but different gss service")
+Cc: stable at vger.kernel.org
+Link: https://bugzilla.opensuse.org/show_bug.cgi?id=1011250
+Signed-off-by: NeilBrown <neilb at suse.com>
+Signed-off-by: Trond Myklebust <trond.myklebust at primarydata.com>
+---
+ net/sunrpc/auth_gss/auth_gss.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index 3dfd769dc5b5..16cea00c959b 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -541,9 +541,13 @@ gss_setup_upcall(struct gss_auth *gss_auth, struct rpc_cred *cred)
+ 		return gss_new;
+ 	gss_msg = gss_add_msg(gss_new);
+ 	if (gss_msg == gss_new) {
+-		int res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg);
++		int res;
++		atomic_inc(&gss_msg->count);
++		res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg);
+ 		if (res) {
+ 			gss_unhash_msg(gss_new);
++			atomic_dec(&gss_msg->count);
++			gss_release_msg(gss_new);
+ 			gss_msg = ERR_PTR(res);
+ 		}
+ 	} else
+@@ -836,6 +840,7 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
+ 			warn_gssd();
+ 		gss_release_msg(gss_msg);
+ 	}
++	gss_release_msg(gss_msg);
+ }
+ 
+ static void gss_pipe_dentry_destroy(struct dentry *dir,
+-- 
+2.11.0
+
diff --git a/debian/patches/series b/debian/patches/series
index 43ccd0f..00241ec 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -247,6 +247,7 @@ bugfix/all/fuse-propagate-dentry-down-to-inode_change_ok.patch
 bugfix/all/fs-give-dentry-to-inode_change_ok-instead-of-inode.patch
 bugfix/all/-xen-blkfront-fix-accounting-of-reqs-when-migrating.patch
 bugfix/all/locking-mutex-don-t-assume-task_running.patch
+bugfix/all/SUNRPC-fix-refcounting-problems-with-auth_gss-messag.patch
 
 # memfd_create() & kdbus backport
 features/all/kdbus/mm-allow-drivers-to-prevent-new-writable-mappings.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list