[PATCH 5.4 56/61] rxrpc: Fix memory leak in rxrpc_lookup_local

From: Greg Kroah-Hartman
Date: Tue Feb 02 2021 - 09:11:21 EST


From: Takeshi Misawa <jeliantsurux@xxxxxxxxx>

commit b8323f7288abd71794cd7b11a4c0a38b8637c8b5 upstream.

Commit 9ebeddef58c4 ("rxrpc: rxrpc_peer needs to hold a ref on the rxrpc_local record")
Then release ref in __rxrpc_put_peer and rxrpc_put_peer_locked.

struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *local, gfp_t gfp)
- peer->local = local;
+ peer->local = rxrpc_get_local(local);

rxrpc_discard_prealloc also need ref release in discarding.

syzbot report:
BUG: memory leak
unreferenced object 0xffff8881080ddc00 (size 256):
comm "syz-executor339", pid 8462, jiffies 4294942238 (age 12.350s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 0a 00 00 00 00 c0 00 08 81 88 ff ff ................
backtrace:
[<000000002b6e495f>] kmalloc include/linux/slab.h:552 [inline]
[<000000002b6e495f>] kzalloc include/linux/slab.h:682 [inline]
[<000000002b6e495f>] rxrpc_alloc_local net/rxrpc/local_object.c:79 [inline]
[<000000002b6e495f>] rxrpc_lookup_local+0x1c1/0x760 net/rxrpc/local_object.c:244
[<000000006b43a77b>] rxrpc_bind+0x174/0x240 net/rxrpc/af_rxrpc.c:149
[<00000000fd447a55>] afs_open_socket+0xdb/0x200 fs/afs/rxrpc.c:64
[<000000007fd8867c>] afs_net_init+0x2b4/0x340 fs/afs/main.c:126
[<0000000063d80ec1>] ops_init+0x4e/0x190 net/core/net_namespace.c:152
[<00000000073c5efa>] setup_net+0xde/0x2d0 net/core/net_namespace.c:342
[<00000000a6744d5b>] copy_net_ns+0x19f/0x3e0 net/core/net_namespace.c:483
[<0000000017d3aec3>] create_new_namespaces+0x199/0x4f0 kernel/nsproxy.c:110
[<00000000186271ef>] unshare_nsproxy_namespaces+0x9b/0x120 kernel/nsproxy.c:226
[<000000002de7bac4>] ksys_unshare+0x2fe/0x5c0 kernel/fork.c:2957
[<00000000349b12ba>] __do_sys_unshare kernel/fork.c:3025 [inline]
[<00000000349b12ba>] __se_sys_unshare kernel/fork.c:3023 [inline]
[<00000000349b12ba>] __x64_sys_unshare+0x12/0x20 kernel/fork.c:3023
[<000000006d178ef7>] do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
[<00000000637076d4>] entry_SYSCALL_64_after_hwframe+0x44/0xa9

Fixes: 9ebeddef58c4 ("rxrpc: rxrpc_peer needs to hold a ref on the rxrpc_local record")
Signed-off-by: Takeshi Misawa <jeliantsurux@xxxxxxxxx>
Reported-and-tested-by: syzbot+305326672fed51b205f7@xxxxxxxxxxxxxxxxxxxxxxxxx
Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
Link: https://lore.kernel.org/r/161183091692.3506637.3206605651502458810.stgit@xxxxxxxxxxxxxxxxxxxxxx
Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
net/rxrpc/call_accept.c | 1 +
1 file changed, 1 insertion(+)

--- a/net/rxrpc/call_accept.c
+++ b/net/rxrpc/call_accept.c
@@ -207,6 +207,7 @@ void rxrpc_discard_prealloc(struct rxrpc
tail = b->peer_backlog_tail;
while (CIRC_CNT(head, tail, size) > 0) {
struct rxrpc_peer *peer = b->peer_backlog[tail];
+ rxrpc_put_local(peer->local);
kfree(peer);
tail = (tail + 1) & (size - 1);
}