android_kernel_oneplus_msm8998/net/sunrpc
NeilBrown 8dc821b9f6 SUNRPC: fix refcounting problems with auth_gss messages.
commit 1cded9d2974fe4fe339fc0ccd6638b80d465ab2c upstream.

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")
Link: https://bugzilla.opensuse.org/show_bug.cgi?id=1011250
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-04-21 09:30:08 +02:00
..
auth_gss SUNRPC: fix refcounting problems with auth_gss messages. 2017-04-21 09:30:08 +02:00
xprtrdma svcrdma: avoid duplicate dma unmapping during error recovery 2017-01-26 08:23:48 +01:00
addr.c
auth.c kernel/params: constify struct kernel_param_ops uses 2015-05-28 11:32:10 +09:30
auth_generic.c
auth_null.c
auth_unix.c sunrpc: increase UNX_MAXNODENAME from 32 to __NEW_UTS_LEN bytes 2015-08-12 14:31:04 -04:00
backchannel_rqst.c SUNRPC: Fix callback channel 2015-12-07 13:04:59 -08:00
cache.c sunrpc/cache: drop reference when sunrpc_cache_pipe_upcall() detects a race 2016-05-04 14:48:54 -07:00
clnt.c SUNRPC: cleanup ida information when removing sunrpc module 2017-02-01 08:30:53 +01:00
debugfs.c SUNRPC: Address kbuild warning in net/sunrpc/debugfs.c 2015-06-11 14:01:06 -04:00
Kconfig rpcrdma: Merge svcrdma and xprtrdma modules into one 2015-06-04 16:56:02 -04:00
Makefile NFS client updates for Linux 4.2 2015-07-02 11:32:23 -07:00
netns.h
rpc_pipe.c VFS: net/: d_inode() annotations 2015-04-15 15:06:56 -04:00
rpcb_clnt.c SUNRPC: NULL utsname dereference on NFS umount during namespace cleanup 2015-02-03 16:40:17 -05:00
sched.c sched/wait: Fix the signal handling fix 2015-12-13 14:30:59 -08:00
socklib.c
stats.c sunrpc: add rpc_count_iostats_idx 2015-02-03 11:06:38 -08:00
sunrpc.h
sunrpc_syms.c SUNRPC: cleanup ida information when removing sunrpc module 2017-02-01 08:30:53 +01:00
svc.c NFS: Don't drop CB requests with invalid principals 2016-10-07 15:23:45 +02:00
svc_xprt.c nfsd/sunrpc: turn enqueueing a svc_xprt into a svc_serv operation 2015-08-10 16:05:42 -04:00
svcauth.c
svcauth_unix.c
svcsock.c svcrpc: document lack of some memory barriers 2015-11-10 17:02:47 -05:00
sysctl.c Sunrpc: Supports hexadecimal number for sysctl files of sunrpc debug 2015-11-03 15:56:49 -05:00
timer.c
xdr.c rpc: fix xdr_truncate_encode to handle buffer ending on page boundary 2015-01-07 14:03:58 -05:00
xprt.c SUNRPC: Lock the transport layer on shutdown 2015-09-19 16:37:43 -04:00
xprtsock.c sunrpc: fix write space race causing stalls 2016-10-28 03:01:31 -04:00