summaryrefslogtreecommitdiff
path: root/ipc/ipc_sysctl.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-11-16 16:55:19 +1100
committerGreg Kroah-Hartman <gregkh@suse.de>2011-01-07 13:58:17 -0800
commite98a198d7100de320d794ba26d03e087cc3c230d (patch)
tree4f10b3a126c61195c5b0b8391dd50d7d26f5df35 /ipc/ipc_sysctl.c
parent03fae048803670d7dd25083fd7995a7b54ab9437 (diff)
sunrpc: prevent use-after-free on clearing XPT_BUSY
commit ed2849d3ecfa339435818eeff28f6c3424300cec upstream. When an xprt is created, it has a refcount of 1, and XPT_BUSY is set. The refcount is *not* owned by the thread that created the xprt (as is clear from the fact that creators never put the reference). Rather, it is owned by the absence of XPT_DEAD. Once XPT_DEAD is set, (And XPT_BUSY is clear) that initial reference is dropped and the xprt can be freed. So when a creator clears XPT_BUSY it is dropping its only reference and so must not touch the xprt again. However svc_recv, after calling ->xpo_accept (and so getting an XPT_BUSY reference on a new xprt), calls svc_xprt_recieved. This clears XPT_BUSY and then svc_xprt_enqueue - this last without owning a reference. This is dangerous and has been seen to leave svc_xprt_enqueue working with an xprt containing garbage. So we need to hold an extra counted reference over that call to svc_xprt_received. For safety, any time we clear XPT_BUSY and then use the xprt again, we first get a reference, and the put it again afterwards. Note that svc_close_all does not need this extra protection as there are no threads running, and the final free can only be called asynchronously from such a thread. Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'ipc/ipc_sysctl.c')
0 files changed, 0 insertions, 0 deletions