From ab9befbe4118850bcd58b33064f020d69b44dea6 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 7 Nov 2017 20:14:43 +0900 Subject: netlink: make sure we reserve space for NLMSG_DONE Otherwise, if messages pack really close together, we'll exceed the size of the sk_buff and return ENOBUFS. I suspect this has been the cause of a lot of weird bugs that people just worked around by increasing the receive buffer size. This actually addresses the root cause. --- src/compat/compat.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/compat/compat.h') diff --git a/src/compat/compat.h b/src/compat/compat.h index 9ec73ba..e4dd226 100644 --- a/src/compat/compat.h +++ b/src/compat/compat.h @@ -454,16 +454,31 @@ static inline struct nlattr **genl_family_attrbuf(const struct genl_family *fami #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) #define get_device_dump(a, b) get_device_dump_real(a, b); \ static int get_device_dump(a, b) { \ + int ret; \ struct wireguard_device *wg = (struct wireguard_device *)cb->args[0]; \ if (!wg) { \ int ret = get_device_start(cb); \ if (ret) \ return ret; \ } \ - return get_device_dump_real(skb, cb); \ + /* https://patchwork.kernel.org/patch/10046511/ */ \ + skb->end -= nlmsg_total_size(sizeof(int)); \ + ret = get_device_dump_real(skb, cb); \ + skb->end += nlmsg_total_size(sizeof(int)); \ + return ret; \ } \ static int get_device_dump_real(a, b) #define COMPAT_CANNOT_USE_NETLINK_START +#else /* https://patchwork.kernel.org/patch/10046511/ */ +#define get_device_dump(a, b) get_device_dump_real(a, b); \ +static int get_device_dump(a, b) { \ + int ret; \ + skb->end -= nlmsg_total_size(sizeof(int)); \ + ret = get_device_dump_real(skb, cb); \ + skb->end += nlmsg_total_size(sizeof(int)); \ + return ret; \ +} \ +static int get_device_dump_real(a, b) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -- cgit v1.2.3-59-g8ed1b