From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f43.google.com (mail-ej1-f43.google.com [209.85.218.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23EA038423B for ; Wed, 2 Sep 2026 15:47:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.43 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788364057; cv=none; b=Epn0Jrlfqm8MoT8AnfV+kxt/Y/aAQnMwoTSvAAZaXjxCVNu5cHJ4rldyClj+vo95uGNMLQpSyGSTb6rawvhPs2iTJVdpq1BmMSfS/WBGzel4lN8rJmLGRXZLqwqqD4ByjmIvZ/R7Ua1pUXLSRDa5QRg4Bhc1vYnWKgmqWhB40bE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788364057; c=relaxed/simple; bh=futA2E2BI054EkkMAf/9xxA4miiP4yekF1HvC97jZpE=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=YAeyQ7AYRbeguqs8pnoRoiPMjX8h2asjFhfQtYS+54c8BDYKhzUXjnMdU3w7fjBhE6B53+xDL7eXioHLVZtqpoIBT3vZBNK6q48f5I/kdOXKPXO/vi71tznR37buWH7jwaqHesSx1nrJgeRznAkJWBRdzpnfMRojAqO1DBqp7UE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=MVhCjgx+; arc=none smtp.client-ip=209.85.218.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MVhCjgx+" Received: by mail-ej1-f43.google.com with SMTP id a640c23a62f3a-c169ae1cb26so397154766b.1 for ; Wed, 02 Sep 2026 08:47:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788364052; x=1788968852; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=q3wYS5mR5Zx6Crt9XdIdwTT/Ll3ikWEO9/OJNepkXHY=; b=MVhCjgx+U7G8QMONbWrIwE7QOXm2Hm54S1glwX2avnEcclTVaBvmzl8mdDHXi7WYRL t145YKiHQHUcI3bhoWlHv2RxGTt5Ln+iNU7ELGRsxwSeq+mlBxqUHVuAH+i2ZKPWyynU SviLCeweDyiY5ZbLbHkuvog7hAf2G8oSXNcbTlVuegt7ccoaN4pOJmL5KsbLysuSyaGm fag6W1v1fbzeKf2XR36nos43wff0WShdOnJvrST4czeJBCK5dI4RRmyxM5z0hXl7wXtW T/3Q5AT96//z88KeE1zacyBXHYXDamWvh6Z31w5Qe7+/q/QkYJRdtnhAhHHuAAhyFhRZ BRrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788364052; x=1788968852; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=q3wYS5mR5Zx6Crt9XdIdwTT/Ll3ikWEO9/OJNepkXHY=; b=MasPVfkkIXqE8Ba8deztcOqgf4HzlL5FdmyMR7WFMdyDy8TuAi9UlYBFD3D7P0WzmU hbVeRa0KC70PreZZ3HxRomBY21W3J19ti8yv0WBG81M/s4e2wh69D/Gljde8BzQJedIi NFQ6C3rpmTb4zS7mTXUb4aqIRPkShEo54xgBWQWlE84eObTPf51wdjnEVivXKq6PaSZ3 4FLAI7RaMzFYAjIN/C/20YCjha/sA5NUv6VFOBnIkNy/UjYOMiQXB9mgXqfsDo5FZy0K jJ/LcwbUQlGhYjr0n3y6GIATjtEasfJ0qEmsauSVPJiu4t5jqJCc549THrRtJ0BBxurI GA7g== X-Forwarded-Encrypted: i=1; AKwUvByIBwKdyt0G5cFMnDEcuD6D54LSSUfUhPym+NHaf7OXAeprbMLUuTy/47L+z9eE0yPr0Wd5Ct6H3kuAv38=@vger.kernel.org X-Gm-Message-State: AFuF++lagzQiWFUCPvoSMISItAmsY600PdzGYwnFw9zv6kUh96aup8sr g98Q2yd8jzf/AJrs4hqmhUrdyBrCGLNMcMRUbw1nNfW4cTLuieC3ZCjW X-Gm-Gg: AYBFou2eBEP7LZWGQYoVyYi+933scC8Rjw8hrNgL53ZL6i4XZz0bcK+58N/nG4RIAZE 65NFAxQhdJbGdJwq8x8DOH0nAoUejE9ZPEoPFR9ZkI1i1eLWDrZKZm3XumyiO+OIwbcnakZ9+HO FSco3eKlNybw5qKdGGO7wkmV/uBLKt/K5DGBq0uNaAQbzO5UGUHehMWHvgT2DEEZfH3Iolhv/zp sGxEwX5Ze+bMOJ7mowN5Vi44jClDWXMitXCKUHsgRPsgHAtlEQHbawzfJpzwnxULbNcr8DZ1Zpq NVPAHMnL4WOnROGZr/dM26olOjNSdY7OBsRalSagCghReANvby17LLr4F/rTdsEkzHDdHRVlKsN gbXYsvZNX/uqkVFc1hkCS0sC2nG2iYU5Nx5MbJCJiFbQbJBjWI7SRQ0rbyMPVMCUKFkxtkwoMRc 12Tohh2VFKuUDCfgyUbhJ4PFCamRcGkkQpao8CGXOyB1s3uYmFJu0tUjeGUhyRei0E7WAKknkGB 6LM/Q8RD7rX/Q== X-Received: by 2002:a17:906:618a:b0:c25:8bf0:36e2 with SMTP id a640c23a62f3a-c25f0187452mr6712366b.10.1788364052039; Wed, 02 Sep 2026 08:47:32 -0700 (PDT) Received: from kali ([169.224.126.247]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48448e72c28sm7532741f8f.6.2026.09.02.08.47.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Sep 2026 08:47:31 -0700 (PDT) From: Ali Firas To: netdev@vger.kernel.org Cc: kuba@kernel.org, pabeni@redhat.com, davem@davemloft.net, edumazet@google.com, andrew+netdev@lunn.ch, idosch@nvidia.com, razor@blackwall.org, stable@vger.kernel.org, linux-kernel@vger.kernel.org, Ali Firas Subject: [PATCH net v2] vxlan: vnifilter: validate the VNI range in vni_filter_entry_policy Date: Wed, 2 Sep 2026 18:46:09 +0300 Message-ID: <20260902154609.594009-1-alishmery18@gmail.com> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit VXLAN_VNIFILTER_ENTRY_START and VXLAN_VNIFILTER_ENTRY_END are declared as bare NLA_U32, so neither is range-checked before vxlan_process_vni_filter() passes them to vxlan_vni_add_del(): int v, err = 0; for (v = start_vni; v <= end_vni; v++) { v is int and end_vni is __u32, so the comparison is unsigned. With end_vni == U32_MAX the loop cannot terminate through its own condition: v reaches U32_MAX, wraps to 0, and 0 <= U32_MAX is true again, so the request never returns. It runs under rtnl_lock, which is global rather than per-netns, so every network configuration operation on the host blocks for as long as it runs, in every namespace. The interface is reachable without privilege: creating the device and adding VNIs only requires CAP_NET_ADMIN in the network namespace's user namespace, so an unprivileged user inside unshare(CLONE_NEWUSER | CLONE_NEWNET) can trigger this with a single netlink message. A VNI at or above VXLAN_N_VID is also accepted and stored, although the VXLAN header carries only 24 bits. The MDB interface in the same driver already range-validates its VNI attributes with an identical constraint (vxlan_mdb.c, vni_range with .max = VXLAN_N_VID - 1). Apply the same validation here. This removes the non-terminating case and rejects VNIs the header cannot carry. It does not bound the cost of a request spanning the whole legitimate 24-bit space: that still creates 2^24 nodes, each with a per-CPU stats block, under rtnl_lock and with no reschedule point, and neither allocation carries __GFP_ACCOUNT. Bounding or accounting that is a separate change and is not attempted here. Tested in a QEMU guest on a KASAN kernel with 2G of memory, as an unprivileged uid inside unshare(CLONE_NEWUSER | CLONE_NEWNET). Before the change, a request with START=0 and END=0xFFFFFFFF drives a global OOM with the allocating task in vxlan_vnifilter_process(); after it, the same request is rejected and in-range VNI addition is unaffected. A request spanning the full in-range space, START=0 END=0xFFFFFF, still exhausts memory on that guest both before and after, as described above. Reproducer available on request. Fixes: f9c4bb0b245c ("vxlan: vni filtering support on collect metadata device") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Ali Firas --- v2: rewrite the changelog to describe only what the patch closes and state explicitly that the cost of a full in-range request is not bounded here. No code changes. v1: https://lore.kernel.org/netdev/20260829030041.940594-1-alishmery18@gmail.com/ drivers/net/vxlan/vxlan_vnifilter.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_vnifilter.c index dd94085e0886..9e86ac39cf9d 100644 --- a/drivers/net/vxlan/vxlan_vnifilter.c +++ b/drivers/net/vxlan/vxlan_vnifilter.c @@ -459,9 +459,15 @@ static int vxlan_vnifilter_dump(struct sk_buff *skb, struct netlink_callback *cb return err; } +static const struct netlink_range_validation vni_filter_vni_range = { + .max = VXLAN_N_VID - 1, +}; + static const struct nla_policy vni_filter_entry_policy[VXLAN_VNIFILTER_ENTRY_MAX + 1] = { - [VXLAN_VNIFILTER_ENTRY_START] = { .type = NLA_U32 }, - [VXLAN_VNIFILTER_ENTRY_END] = { .type = NLA_U32 }, + [VXLAN_VNIFILTER_ENTRY_START] = NLA_POLICY_FULL_RANGE(NLA_U32, + &vni_filter_vni_range), + [VXLAN_VNIFILTER_ENTRY_END] = NLA_POLICY_FULL_RANGE(NLA_U32, + &vni_filter_vni_range), [VXLAN_VNIFILTER_ENTRY_GROUP] = NLA_POLICY_EXACT_LEN(sizeof_field(struct iphdr, daddr)), [VXLAN_VNIFILTER_ENTRY_GROUP6] = NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)), }; -- 2.53.0