summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMarek Majtyka <marekx.majtyka@intel.com>2020-11-20 16:14:43 +0100
committerDaniel Borkmann <daniel@iogearbox.net>2020-11-23 13:19:33 +0100
commit178648916e73e00de83150eb0c90c0d3a977a46a (patch)
treeabe8a8d65163c3c88bb803a63073d12d4b29042e /net
parentxsk: Fix umem cleanup bug at socket destruct (diff)
downloadlinux-178648916e73e00de83150eb0c90c0d3a977a46a.tar.xz
linux-178648916e73e00de83150eb0c90c0d3a977a46a.zip
xsk: Fix incorrect netdev reference count
Fix incorrect netdev reference count in xsk_bind operation. Incorrect reference count of the device appears when a user calls bind with the XDP_ZEROCOPY flag on an interface which does not support zero-copy. In such a case, an error is returned but the reference count is not decreased. This change fixes the fault, by decreasing the reference count in case of such an error. The problem being corrected appeared in '162c820ed896' for the first time, and the code was moved to new file location over the time with commit 'c2d3d6a47462'. This specific patch applies to all version starting from 'c2d3d6a47462'. The same solution should be applied but on different file (net/xdp/xdp_umem.c) and function (xdp_umem_assign_dev) for versions from '162c820ed896' to 'c2d3d6a47462' excluded. Fixes: 162c820ed896 ("xdp: hold device for umem regardless of zero-copy mode") Signed-off-by: Marek Majtyka <marekx.majtyka@intel.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Magnus Karlsson <magnus.karlsson@intel.com> Link: https://lore.kernel.org/bpf/20201120151443.105903-1-marekx.majtyka@intel.com
Diffstat (limited to 'net')
-rw-r--r--net/xdp/xsk_buff_pool.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index 3c5a1423d922..9287eddec52c 100644
--- a/net/xdp/xsk_buff_pool.c
+++ b/net/xdp/xsk_buff_pool.c
@@ -185,8 +185,10 @@ err_unreg_xsk:
err_unreg_pool:
if (!force_zc)
err = 0; /* fallback to copy mode */
- if (err)
+ if (err) {
xsk_clear_pool_at_qid(netdev, queue_id);
+ dev_put(netdev);
+ }
return err;
}