From patchwork Fri Sep 20 10:20:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Massimiliano Pellizzer X-Patchwork-Id: 1987873 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X97hq2h8xz1y31 for ; Fri, 20 Sep 2024 20:21:30 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1sralJ-0005V0-Ng; Fri, 20 Sep 2024 10:21:17 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1sralH-0005UD-V8 for kernel-team@lists.ubuntu.com; Fri, 20 Sep 2024 10:21:15 +0000 Received: from mail-ed1-f69.google.com (mail-ed1-f69.google.com [209.85.208.69]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id A406F40A84 for ; Fri, 20 Sep 2024 10:21:15 +0000 (UTC) Received: by mail-ed1-f69.google.com with SMTP id 4fb4d7f45d1cf-5c25680de68so1215097a12.2 for ; Fri, 20 Sep 2024 03:21:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726827675; x=1727432475; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pUK7aMytp1uPTTa10DaphO4GtvNOqL2er2i3cMOL5es=; b=ejc8w6kAPgy7mDmuCcQc9QbZzwTYnQeoZ0DKd7rLm2Hy/HMFCSZGKTX5QYtPiLQaCX 9y4kmr6z8SEAMv+WS1WKYLPV74zW4Rj9x355efucuC3TToiaKFmiaAycuZH5rUBm8Kul 98cC4qV23FMBRAgfCU029zjRT55wQCpwdSJTwMlZCygniqLHiK3WOkFT0+hg45GBQsKn jEgDm0TIP9yjz3ognqPifwPLHkmLLHKQysMr3rzG4VNFdzMhZmBvcWSulQnpDYn4C5os bDvd+34Abat5dfwGWcFRTAO6gZTD8+YjBLX6o6DIxu3o0dV9a9YPku4unc5/5sGRm3M6 2zzg== X-Gm-Message-State: AOJu0Yy7tNYyoca+5bx7wihfUn4+S10Ai0hr9P71+oRY2DVEexGNy7Nb tqbYwPSvvLwMECmir1YW2ozXhToyl9Zk581efTOa7lq9V+EJXuV6GyWAutlNIwdtipFJICej8Fr 3oVkFqqmJAZjtMPeFRaBp3/Bunu/x20nJxPyx0ERhZVWWsk86KTdAdmJN8oUew1mPDHUHpGxthg T/bwgIQgKobw== X-Received: by 2002:a17:907:e25a:b0:a86:8832:2fb7 with SMTP id a640c23a62f3a-a90d4fe825bmr169235366b.20.1726827674886; Fri, 20 Sep 2024 03:21:14 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFEsfERj+befqoQTcExfb7UL1vYsmZIE9iVL8+vSvAi7MQJhBLT3FMsYEpSD6agzf952mtEIQ== X-Received: by 2002:a17:907:e25a:b0:a86:8832:2fb7 with SMTP id a640c23a62f3a-a90d4fe825bmr169232766b.20.1726827674267; Fri, 20 Sep 2024 03:21:14 -0700 (PDT) Received: from framework-canonical.station (net-93-71-67-182.cust.vodafonedsl.it. [93.71.67.182]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a90610f388esm829104766b.63.2024.09.20.03.21.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Sep 2024 03:21:13 -0700 (PDT) From: Massimiliano Pellizzer To: kernel-team@lists.ubuntu.com Subject: [SRU][F][PATCH 1/2] netfilter: nft_limit: rename stateful structure Date: Fri, 20 Sep 2024 12:20:59 +0200 Message-ID: <20240920102100.36974-2-massimiliano.pellizzer@canonical.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240920102100.36974-1-massimiliano.pellizzer@canonical.com> References: <20240920102100.36974-1-massimiliano.pellizzer@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Pablo Neira Ayuso [ Upstream commit 369b6cb5d391750fc01ce951c2500281d2975705 ] From struct nft_limit to nft_limit_priv. Signed-off-by: Pablo Neira Ayuso Stable-dep-of: 91a139cee120 ("netfilter: nft_limit: do not ignore unsupported flags") Signed-off-by: Sasha Levin (cherry picked from commit 8a6635074a658e3aefec396192947682764c0ac0 linux-5.15.y) CVE-2024-26668 Signed-off-by: Massimiliano Pellizzer --- net/netfilter/nft_limit.c | 104 +++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c index 6e7b92e6f424..cddb5e8c4595 100644 --- a/net/netfilter/nft_limit.c +++ b/net/netfilter/nft_limit.c @@ -14,7 +14,7 @@ #include #include -struct nft_limit { +struct nft_limit_priv { spinlock_t lock; u64 last; u64 tokens; @@ -25,33 +25,33 @@ struct nft_limit { bool invert; }; -static inline bool nft_limit_eval(struct nft_limit *limit, u64 cost) +static inline bool nft_limit_eval(struct nft_limit_priv *priv, u64 cost) { u64 now, tokens; s64 delta; - spin_lock_bh(&limit->lock); + spin_lock_bh(&priv->lock); now = ktime_get_ns(); - tokens = limit->tokens + now - limit->last; - if (tokens > limit->tokens_max) - tokens = limit->tokens_max; + tokens = priv->tokens + now - priv->last; + if (tokens > priv->tokens_max) + tokens = priv->tokens_max; - limit->last = now; + priv->last = now; delta = tokens - cost; if (delta >= 0) { - limit->tokens = delta; - spin_unlock_bh(&limit->lock); - return limit->invert; + priv->tokens = delta; + spin_unlock_bh(&priv->lock); + return priv->invert; } - limit->tokens = tokens; - spin_unlock_bh(&limit->lock); - return !limit->invert; + priv->tokens = tokens; + spin_unlock_bh(&priv->lock); + return !priv->invert; } /* Use same default as in iptables. */ #define NFT_LIMIT_PKT_BURST_DEFAULT 5 -static int nft_limit_init(struct nft_limit *limit, +static int nft_limit_init(struct nft_limit_priv *priv, const struct nlattr * const tb[], bool pkts) { u64 unit, tokens; @@ -60,58 +60,58 @@ static int nft_limit_init(struct nft_limit *limit, tb[NFTA_LIMIT_UNIT] == NULL) return -EINVAL; - limit->rate = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_RATE])); + priv->rate = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_RATE])); unit = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_UNIT])); - limit->nsecs = unit * NSEC_PER_SEC; - if (limit->rate == 0 || limit->nsecs < unit) + priv->nsecs = unit * NSEC_PER_SEC; + if (priv->rate == 0 || priv->nsecs < unit) return -EOVERFLOW; if (tb[NFTA_LIMIT_BURST]) - limit->burst = ntohl(nla_get_be32(tb[NFTA_LIMIT_BURST])); + priv->burst = ntohl(nla_get_be32(tb[NFTA_LIMIT_BURST])); - if (pkts && limit->burst == 0) - limit->burst = NFT_LIMIT_PKT_BURST_DEFAULT; + if (pkts && priv->burst == 0) + priv->burst = NFT_LIMIT_PKT_BURST_DEFAULT; - if (limit->rate + limit->burst < limit->rate) + if (priv->rate + priv->burst < priv->rate) return -EOVERFLOW; if (pkts) { - tokens = div64_u64(limit->nsecs, limit->rate) * limit->burst; + tokens = div64_u64(priv->nsecs, priv->rate) * priv->burst; } else { /* The token bucket size limits the number of tokens can be * accumulated. tokens_max specifies the bucket size. * tokens_max = unit * (rate + burst) / rate. */ - tokens = div64_u64(limit->nsecs * (limit->rate + limit->burst), - limit->rate); + tokens = div64_u64(priv->nsecs * (priv->rate + priv->burst), + priv->rate); } - limit->tokens = tokens; - limit->tokens_max = limit->tokens; + priv->tokens = tokens; + priv->tokens_max = priv->tokens; if (tb[NFTA_LIMIT_FLAGS]) { u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS])); if (flags & NFT_LIMIT_F_INV) - limit->invert = true; + priv->invert = true; } - limit->last = ktime_get_ns(); - spin_lock_init(&limit->lock); + priv->last = ktime_get_ns(); + spin_lock_init(&priv->lock); return 0; } -static int nft_limit_dump(struct sk_buff *skb, const struct nft_limit *limit, +static int nft_limit_dump(struct sk_buff *skb, const struct nft_limit_priv *priv, enum nft_limit_type type) { - u32 flags = limit->invert ? NFT_LIMIT_F_INV : 0; - u64 secs = div_u64(limit->nsecs, NSEC_PER_SEC); + u32 flags = priv->invert ? NFT_LIMIT_F_INV : 0; + u64 secs = div_u64(priv->nsecs, NSEC_PER_SEC); - if (nla_put_be64(skb, NFTA_LIMIT_RATE, cpu_to_be64(limit->rate), + if (nla_put_be64(skb, NFTA_LIMIT_RATE, cpu_to_be64(priv->rate), NFTA_LIMIT_PAD) || nla_put_be64(skb, NFTA_LIMIT_UNIT, cpu_to_be64(secs), NFTA_LIMIT_PAD) || - nla_put_be32(skb, NFTA_LIMIT_BURST, htonl(limit->burst)) || + nla_put_be32(skb, NFTA_LIMIT_BURST, htonl(priv->burst)) || nla_put_be32(skb, NFTA_LIMIT_TYPE, htonl(type)) || nla_put_be32(skb, NFTA_LIMIT_FLAGS, htonl(flags))) goto nla_put_failure; @@ -121,8 +121,8 @@ static int nft_limit_dump(struct sk_buff *skb, const struct nft_limit *limit, return -1; } -struct nft_limit_pkts { - struct nft_limit limit; +struct nft_limit_priv_pkts { + struct nft_limit_priv limit; u64 cost; }; @@ -130,7 +130,7 @@ static void nft_limit_pkts_eval(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) { - struct nft_limit_pkts *priv = nft_expr_priv(expr); + struct nft_limit_priv_pkts *priv = nft_expr_priv(expr); if (nft_limit_eval(&priv->limit, priv->cost)) regs->verdict.code = NFT_BREAK; @@ -148,7 +148,7 @@ static int nft_limit_pkts_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { - struct nft_limit_pkts *priv = nft_expr_priv(expr); + struct nft_limit_priv_pkts *priv = nft_expr_priv(expr); int err; err = nft_limit_init(&priv->limit, tb, true); @@ -161,7 +161,7 @@ static int nft_limit_pkts_init(const struct nft_ctx *ctx, static int nft_limit_pkts_dump(struct sk_buff *skb, const struct nft_expr *expr) { - const struct nft_limit_pkts *priv = nft_expr_priv(expr); + const struct nft_limit_priv_pkts *priv = nft_expr_priv(expr); return nft_limit_dump(skb, &priv->limit, NFT_LIMIT_PKTS); } @@ -169,7 +169,7 @@ static int nft_limit_pkts_dump(struct sk_buff *skb, const struct nft_expr *expr) static struct nft_expr_type nft_limit_type; static const struct nft_expr_ops nft_limit_pkts_ops = { .type = &nft_limit_type, - .size = NFT_EXPR_SIZE(sizeof(struct nft_limit_pkts)), + .size = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv_pkts)), .eval = nft_limit_pkts_eval, .init = nft_limit_pkts_init, .dump = nft_limit_pkts_dump, @@ -179,7 +179,7 @@ static void nft_limit_bytes_eval(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) { - struct nft_limit *priv = nft_expr_priv(expr); + struct nft_limit_priv *priv = nft_expr_priv(expr); u64 cost = div64_u64(priv->nsecs * pkt->skb->len, priv->rate); if (nft_limit_eval(priv, cost)) @@ -190,7 +190,7 @@ static int nft_limit_bytes_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { - struct nft_limit *priv = nft_expr_priv(expr); + struct nft_limit_priv *priv = nft_expr_priv(expr); return nft_limit_init(priv, tb, false); } @@ -198,14 +198,14 @@ static int nft_limit_bytes_init(const struct nft_ctx *ctx, static int nft_limit_bytes_dump(struct sk_buff *skb, const struct nft_expr *expr) { - const struct nft_limit *priv = nft_expr_priv(expr); + const struct nft_limit_priv *priv = nft_expr_priv(expr); return nft_limit_dump(skb, priv, NFT_LIMIT_PKT_BYTES); } static const struct nft_expr_ops nft_limit_bytes_ops = { .type = &nft_limit_type, - .size = NFT_EXPR_SIZE(sizeof(struct nft_limit)), + .size = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv)), .eval = nft_limit_bytes_eval, .init = nft_limit_bytes_init, .dump = nft_limit_bytes_dump, @@ -240,7 +240,7 @@ static void nft_limit_obj_pkts_eval(struct nft_object *obj, struct nft_regs *regs, const struct nft_pktinfo *pkt) { - struct nft_limit_pkts *priv = nft_obj_data(obj); + struct nft_limit_priv_pkts *priv = nft_obj_data(obj); if (nft_limit_eval(&priv->limit, priv->cost)) regs->verdict.code = NFT_BREAK; @@ -250,7 +250,7 @@ static int nft_limit_obj_pkts_init(const struct nft_ctx *ctx, const struct nlattr * const tb[], struct nft_object *obj) { - struct nft_limit_pkts *priv = nft_obj_data(obj); + struct nft_limit_priv_pkts *priv = nft_obj_data(obj); int err; err = nft_limit_init(&priv->limit, tb, true); @@ -265,7 +265,7 @@ static int nft_limit_obj_pkts_dump(struct sk_buff *skb, struct nft_object *obj, bool reset) { - const struct nft_limit_pkts *priv = nft_obj_data(obj); + const struct nft_limit_priv_pkts *priv = nft_obj_data(obj); return nft_limit_dump(skb, &priv->limit, NFT_LIMIT_PKTS); } @@ -273,7 +273,7 @@ static int nft_limit_obj_pkts_dump(struct sk_buff *skb, static struct nft_object_type nft_limit_obj_type; static const struct nft_object_ops nft_limit_obj_pkts_ops = { .type = &nft_limit_obj_type, - .size = NFT_EXPR_SIZE(sizeof(struct nft_limit_pkts)), + .size = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv_pkts)), .init = nft_limit_obj_pkts_init, .eval = nft_limit_obj_pkts_eval, .dump = nft_limit_obj_pkts_dump, @@ -283,7 +283,7 @@ static void nft_limit_obj_bytes_eval(struct nft_object *obj, struct nft_regs *regs, const struct nft_pktinfo *pkt) { - struct nft_limit *priv = nft_obj_data(obj); + struct nft_limit_priv *priv = nft_obj_data(obj); u64 cost = div64_u64(priv->nsecs * pkt->skb->len, priv->rate); if (nft_limit_eval(priv, cost)) @@ -294,7 +294,7 @@ static int nft_limit_obj_bytes_init(const struct nft_ctx *ctx, const struct nlattr * const tb[], struct nft_object *obj) { - struct nft_limit *priv = nft_obj_data(obj); + struct nft_limit_priv *priv = nft_obj_data(obj); return nft_limit_init(priv, tb, false); } @@ -303,7 +303,7 @@ static int nft_limit_obj_bytes_dump(struct sk_buff *skb, struct nft_object *obj, bool reset) { - const struct nft_limit *priv = nft_obj_data(obj); + const struct nft_limit_priv *priv = nft_obj_data(obj); return nft_limit_dump(skb, priv, NFT_LIMIT_PKT_BYTES); } @@ -311,7 +311,7 @@ static int nft_limit_obj_bytes_dump(struct sk_buff *skb, static struct nft_object_type nft_limit_obj_type; static const struct nft_object_ops nft_limit_obj_bytes_ops = { .type = &nft_limit_obj_type, - .size = sizeof(struct nft_limit), + .size = sizeof(struct nft_limit_priv), .init = nft_limit_obj_bytes_init, .eval = nft_limit_obj_bytes_eval, .dump = nft_limit_obj_bytes_dump, From patchwork Fri Sep 20 10:21:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Massimiliano Pellizzer X-Patchwork-Id: 1987872 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X97hq28Kfz1y2j for ; Fri, 20 Sep 2024 20:21:30 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1sralO-0005Wj-1i; Fri, 20 Sep 2024 10:21:22 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1sralK-0005UV-2k for kernel-team@lists.ubuntu.com; Fri, 20 Sep 2024 10:21:18 +0000 Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 8B0AA40A84 for ; Fri, 20 Sep 2024 10:21:16 +0000 (UTC) Received: by mail-ej1-f72.google.com with SMTP id a640c23a62f3a-a8d21b5cb5fso107557766b.0 for ; Fri, 20 Sep 2024 03:21:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726827676; x=1727432476; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xW7n2xUMuQiutbPmG2taTp7+tjyZ5hJR+t9OGgeE5OA=; b=Cr3KxAjeh1qgo4Y3S5AJkn1Jc0133JvX+Anp1Z8uROdyU3PBrE47pkwuy017Z5VWd1 Iz6s6nXiOmmEBeThSnBePu97oO0GspTfzaQEQBmOqO2JSAdynqoGsinKrDYIKY1T9cp4 QfJPGWvONjLsaoGjfKd3P2+BYCPAOKlfbDJB2my2zYEWbiiwZ3Pv1l6gf6B2Pt6Yap7L Vf4yLFveXvMhuGuIYp1urG6yAZQtWFXf46SwhbhQ2z+qBpYC7jJeI4FfRDAXsSN/rCk9 LldR3UsHc0U/UCeLk+wCm7NTvzqvb0xiypWUC1GoGsSUCOs331Q9DC87q/A5hCYzCHQn 2LMg== X-Gm-Message-State: AOJu0Ywd0gd5zi1dT6QVwYYAPMQSCau0XHQ21/4+1EhirVRKEAA9p2LZ N9y63euJjEDP3dOS0buL529OqAki7XkIdSqP9fHZlULmyUlnC108IPVv9vMy00nNNMzhUTAoU+3 EmF3XcuHMOd6vDG8K3IFWiMWewdLY8aaOf3mghByUs7vuYodNL3ilEnWkYwns0/0HLKNT5y4n38 3owvcPROcBew== X-Received: by 2002:a17:907:94d4:b0:a8b:6ee7:ba1b with SMTP id a640c23a62f3a-a90d56d8d57mr178383366b.15.1726827675775; Fri, 20 Sep 2024 03:21:15 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFX4RJgv+vIUF3dzXlpA4CcKuREZRAmT0OFHnpkkVcrrkUuTaOPEA0zmmuThWoqlgYotpQTUw== X-Received: by 2002:a17:907:94d4:b0:a8b:6ee7:ba1b with SMTP id a640c23a62f3a-a90d56d8d57mr178380566b.15.1726827675271; Fri, 20 Sep 2024 03:21:15 -0700 (PDT) Received: from framework-canonical.station (net-93-71-67-182.cust.vodafonedsl.it. [93.71.67.182]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a90610f388esm829104766b.63.2024.09.20.03.21.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Sep 2024 03:21:14 -0700 (PDT) From: Massimiliano Pellizzer To: kernel-team@lists.ubuntu.com Subject: [SRU][F][PATCH 2/2] netfilter: nft_limit: reject configurations that cause integer overflow Date: Fri, 20 Sep 2024 12:21:00 +0200 Message-ID: <20240920102100.36974-3-massimiliano.pellizzer@canonical.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240920102100.36974-1-massimiliano.pellizzer@canonical.com> References: <20240920102100.36974-1-massimiliano.pellizzer@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Florian Westphal [ Upstream commit c9d9eb9c53d37cdebbad56b91e40baf42d5a97aa ] Reject bogus configs where internal token counter wraps around. This only occurs with very very large requests, such as 17gbyte/s. Its better to reject this rather than having incorrect ratelimit. Fixes: d2168e849ebf ("netfilter: nft_limit: add per-byte limiting") Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin (backported from commit 79d4efd75e7dbecd855a3b8a63e65f7265f466e1 linux-5.15.y) [mpellizzer: backported solving a conflict due to a variable declaration which does not affect the patch, and casting some variables and constants since the versions of check_mul_overflow and check_add_overflow used expect the arguments to have the same type] CVE-2024-26668 Signed-off-by: Massimiliano Pellizzer --- net/netfilter/nft_limit.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c index cddb5e8c4595..ca168c4bbff4 100644 --- a/net/netfilter/nft_limit.c +++ b/net/netfilter/nft_limit.c @@ -54,16 +54,18 @@ static inline bool nft_limit_eval(struct nft_limit_priv *priv, u64 cost) static int nft_limit_init(struct nft_limit_priv *priv, const struct nlattr * const tb[], bool pkts) { - u64 unit, tokens; + u64 unit, tokens, rate_with_burst; if (tb[NFTA_LIMIT_RATE] == NULL || tb[NFTA_LIMIT_UNIT] == NULL) return -EINVAL; priv->rate = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_RATE])); + if (priv->rate == 0) + return -EINVAL; + unit = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_UNIT])); - priv->nsecs = unit * NSEC_PER_SEC; - if (priv->rate == 0 || priv->nsecs < unit) + if (check_mul_overflow(unit, (u64)NSEC_PER_SEC, &priv->nsecs)) return -EOVERFLOW; if (tb[NFTA_LIMIT_BURST]) @@ -72,18 +74,25 @@ static int nft_limit_init(struct nft_limit_priv *priv, if (pkts && priv->burst == 0) priv->burst = NFT_LIMIT_PKT_BURST_DEFAULT; - if (priv->rate + priv->burst < priv->rate) + if (check_add_overflow(priv->rate, (u64)priv->burst, &rate_with_burst)) return -EOVERFLOW; if (pkts) { - tokens = div64_u64(priv->nsecs, priv->rate) * priv->burst; + u64 tmp = div64_u64(priv->nsecs, priv->rate); + + if (check_mul_overflow(tmp, (u64)priv->burst, &tokens)) + return -EOVERFLOW; } else { + u64 tmp; + /* The token bucket size limits the number of tokens can be * accumulated. tokens_max specifies the bucket size. * tokens_max = unit * (rate + burst) / rate. */ - tokens = div64_u64(priv->nsecs * (priv->rate + priv->burst), - priv->rate); + if (check_mul_overflow(priv->nsecs, rate_with_burst, &tmp)) + return -EOVERFLOW; + + tokens = div64_u64(tmp, priv->rate); } priv->tokens = tokens;