Message ID | 1601112373-10595-1-git-send-email-magnus.karlsson@gmail.com |
---|---|
State | New |
Headers | show |
Series | [bpf-next] xsk: fix possible crash in socket_release when out-of-memory | expand |
On 9/26/20 11:26 AM, Magnus Karlsson wrote: > From: Magnus Karlsson <magnus.karlsson@intel.com> > > Fix possible crash in socket_release when an out-of-memory error has > occurred in the bind call. If a socket using the XDP_SHARED_UMEM flag > encountered an error in xp_create_and_assign_umem, the bind code > jumped to the exit routine but erroneously forgot to set the err value > before jumping. This meant that the exit routine thought the setup > went well and set the state of the socket to XSK_BOUND. The xsk socket > release code will then, at application exit, think that this is a > properly setup socket, when it is not, leading to a crash when all > fields in the socket have in fact not been initialized properly. Fix > this by setting the err variable in xsk_bind so that the socket is not > set to XSK_BOUND which leads to the clean-up in xsk_release not being > triggered. > > Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com> > Reported-by: syzbot+ddc7b4944bc61da19b81@syzkaller.appspotmail.com > Fixes: 1c1efc2af158 ("xsk: Create and free buffer pool independently from umem") Looks good either way, applied, thanks! > I have not been able to reproduce this issue using the syzkaller > config and reproducer, so I cannot guarantee it fixes it. But this bug > is real and it is triggered by an out-of-memory in > xp_create_and_assign_umem, just like syzcaller injects, and would lead > to the same crash in dev_hold in xsk_release. You can just asked syzbot (which I just did on the original report) via: #syz test: git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master Thanks, Daniel
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c index 3895697..ba4dfb1 100644 --- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -703,6 +703,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len) xs->pool = xp_create_and_assign_umem(xs, umem_xs->umem); if (!xs->pool) { + err = -ENOMEM; sockfd_put(sock); goto out_unlock; }