From nobody Sun Jul 26 00:33:30 2026 Received: from mail-ua1-f44.google.com (mail-ua1-f44.google.com [209.85.222.44]) (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 0FB292882D6 for ; Fri, 10 Jul 2026 18:54:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=209.85.222.44 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783709670; cv=pass; b=rICKTikH02E9jgD6tVPzHULu/FDr9XX8/zO98ug8W11NdDuwk+HTCkPIAzAVOaojGG5+ThkcVssTTFnGCy1t0GRFZyRPGoFB48vaR87fknLi9sOwn6/ODEn0dYjSgKP1OgCZN71O4JZ/fROnbWs2wOZsQ8LxRI5YF/EAzVgWR9Q= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783709670; c=relaxed/simple; bh=LRAJT2Po2j5jCh9NWuBWia9Uw1o4w677JrToogmZ484=; h=MIME-Version:From:Date:Message-ID:Subject:To:Cc:Content-Type; b=Eb2bwgaXrlqegloA67VUDrVDY1xO9DLz3EbdCaWWAOICRIFiK9Rxl6IM1vlNyziimnmesg7SpUhteAomceXnc8oI1os+hkrHtMCHiEZHU6HS8I2QnhJ9Rr1GdPgpgFC8h0LNq93jHMkRH0tL54hZeeK8Lmx5mIxBgFzuHrkaC4g= ARC-Authentication-Results: i=2; 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=VsYvyfIe; arc=pass smtp.client-ip=209.85.222.44 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="VsYvyfIe" Received: by mail-ua1-f44.google.com with SMTP id a1e0cc1a2514c-971de219a85so585088241.0 for ; Fri, 10 Jul 2026 11:54:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1783709668; cv=none; d=google.com; s=arc-20260327; b=SKfgKW2BmBcvO/mDW82Nh1uwWfWfIYytdXxP37Sl7F7z7NxvTZYKj8uR57SmZuUjGQ naa68runHjRAKWsrsxXq3n7JbM2VT7uTzFab/a/Y2hN4BZoKKwYl078FE29mB55Y6cPZ d59r4Z1Lf48fa5h8HeIulSaWP8o1cRBDc8ImzjT6XYK7TJILRNqNeRpTh+SBzYFHuk9+ PrjE+QBQjwumlEixhvScQpinQ8po8KJ0n8INgLL47MzR/S6tvBTtgUffRIpvG0McW9TR 6oG0lB/ilmNtEQjaKZeVlt5r7X+iUpf/+OLMEBfXMJgUhPt5MfKLUE02aDC/NRxTzXca glAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=cc:to:subject:message-id:date:from:mime-version:dkim-signature; bh=U1803zTu4Fg0CP/BNLJ3R5b7AQt4yDNGDjkErQd1zms=; fh=MrGOZ0pN3KTgK0bq3h5UEJx5uIDykc2wpiCjTwdEnsg=; b=ZVhMbnERF1Fgnr5HYnXlg2YtU4BakoQtE3y1P+VMOTyOPj9rXNCwwM1czNWsc615WQ VAj2ZnRokcMEkFq7foJIad51QznCpW9z/Q2F2uPTicSzySkX8FYjVkgRjYIrl2QUX5E5 vCp7oZWNGXeXYw+vXJQlQHfxKHq1IcoYQTXodMRMjaIQkrHZfsSWz6U6Ktw19o7miumm dG3MTEolylvQuytNZ9g9nYn+sIRsBdaH3eMCujL2MR1wESeaEekp7gfp9LJu6khnpyuh vaV97wgWvU+sfe2Xl8Cnb5n+uaSwBEfDOxKvgjzfEDmyrD2H4e1vdU3eHlJZ5rmn4qgO lxOA==; darn=vger.kernel.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783709668; x=1784314468; darn=vger.kernel.org; h=content-type:cc:to:subject:message-id:date:from:mime-version:from :to:cc:subject:date:message-id:reply-to:content-type; bh=U1803zTu4Fg0CP/BNLJ3R5b7AQt4yDNGDjkErQd1zms=; b=VsYvyfIem10bKGFnZ6ak+7lNMD+b4q798bEltWwTKIldh9VV1hDP19QsI4BtrShQwh OuSbpI1tnPBrOzDPcxfSun+WrO2bLnTzHmHJTu22Oe5KzKJtm9wNU2DRLgWUy7PTvRZV nqjGyCyqTU6Ol8qgk1uxBk6O9upCxrnV7ucNY9C43gPqV3SHfrXhrryKEGknIPChbPKa TwwurLY+5G8PbIZSs0hakQNhIi704RSKsbtykUAFU4lBKUrOMdRa7lpjHWthZCWfRcL1 UOO5NYN7SeEGvI1LenWhHbxg1iOXDXQZhauMBeXrAofV4fdIjUGFdPJFmkGIhN6Ynw6N 371w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783709668; x=1784314468; h=content-type:cc:to:subject:message-id:date:from:mime-version :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to:content-type; bh=U1803zTu4Fg0CP/BNLJ3R5b7AQt4yDNGDjkErQd1zms=; b=NjqMVKLZPZkE29ZKzaV+LxS5ULlmHTF/B+kbgspsTX6AmgNC8GWDHsHP4d199Z94tL IMlqStRneAVjCb7V2LRnxrg3pld/b76MnMyMjxQUwInB+Ij1XGNkwqSh71sjiaKjo213 MW2yZMUiT4sud+4QYvy9z7zQ53RlQOmcRPfX4vSuFLm+0bdqkgkFZOoCsm+5U8o3Wm4l qhPurIp5Dqg+ZSIwqg2ckQ98PCZr5WFlXE5dyKgk3q1dlcBuQh3W3FHcG6mQeECPgAUx Zhl+DHThwWUJbCmpkKg3C2fRnM6JZ6IV1V2HScOjIUoRftKZDoOZRyL8FQvP1MhxCjTg g0UA== X-Forwarded-Encrypted: i=1; AHgh+Rq5ibZirv79S9+7wPnA+6z3j6nSftMSYKhQ7+oE9XKaHrNXjnRIzt8hat7QZTgEWqV9HK5e+0evhrc7V6o=@vger.kernel.org X-Gm-Message-State: AOJu0Yz5zsFBvtGcU0qRo2JizveWDhaSoKcPKFHBtEJ48ReBMKiMwJ2i 7blFMCOvjbVdfggp3khmif5gH8QRyMzUTMIZtm/S1yn95CxHqEuQJGLajJHLMnqwGAXkJMS9Yin w0uOrpEBsaov6XRxUwIMx3yVO394kOMg= X-Gm-Gg: AfdE7cntTYMhNcy8PP7qxPH4E3UT2xSyhzZwGTHByMZDowYU8iziWmv/ZTF948a4RkP dF1UBOvxLsjwGTrDBpRBSul9OYaJ0/3cfO+Pg1w9gBLQXW5OK2rR4fFB4O5USnlpZe0rAFDpEpD NwDpU2u4tdyLvgTDFLnRhbrqjdTbJuIXT5a9+4IJrAYVHvYxGfsQx5H3PeW0i8cYpPX4QUDCeFx UyCjHketcdGugommMkWGtWJj8o7reFCJLDDGC+lvVYI7fvKq3WGnz50TSOs/s+oXcdUIZRbNg== X-Received: by 2002:a05:6102:390f:b0:737:b102:c1b4 with SMTP id ada2fe7eead31-745367c8d49mr2858137.7.1783709663290; Fri, 10 Jul 2026 11:54:23 -0700 (PDT) Received: from 77377267392 named unknown by gmailapi.google.com with HTTPREST; Fri, 10 Jul 2026 11:54:22 -0700 Received: from 77377267392 named unknown by gmailapi.google.com with HTTPREST; Fri, 10 Jul 2026 11:54:22 -0700 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Laxman Acharya Padhya Date: Fri, 10 Jul 2026 11:54:22 -0700 X-Gm-Features: AUfX_myFkMhQ48S_ET5-Cax5aTFnmBM1HO8JjqsVC_qYlOgexphFEfB2trXuj0o Message-ID: Subject: [PATCH] wifi: mt76: mt7921: validate CLC firmware records To: Felix Fietkau Cc: Lorenzo Bianconi , Ryder Lee , Shayne Chen , Sean Wang , linux-wireless@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The CLC region is supplied by firmware, but the loader trusts the region count and each record length. A malformed image can make the region table pointer precede the firmware buffer, make the record loop fail to advance, or index phy->clc past its end. Validate the table and record bounds before dereferencing or copying. Fixes: 23bdc5d8cadf ("wifi: mt76: mt7921: introduce Country Location Control support") Signed-off-by: Laxman Acharya Padhya --- drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 28 +++++++++++++++++++++= ---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 25b9437250f7..564dd836e0b3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -415,7 +415,8 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name) struct mt76_dev *mdev =3D &dev->mt76; struct mt792x_phy *phy =3D &dev->phy; const struct firmware *fw; - int ret, i, len, offset =3D 0; + size_t clc_len, fw_data_len, len, offset =3D 0; + int ret, i; u8 *clc_base =3D NULL, hw_encap =3D 0; dev->phy.clc_chan_conf =3D 0xff; @@ -441,13 +442,21 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name) } hdr =3D (const void *)(fw->data + fw->size - sizeof(*hdr)); + if (hdr->n_region > (fw->size - sizeof(*hdr)) / sizeof(*region)) { + dev_err(mdev->dev, "Invalid firmware region table\n"); + ret =3D -EINVAL; + goto out; + } + fw_data_len =3D fw->size - sizeof(*hdr) - + hdr->n_region * sizeof(*region); + for (i =3D 0; i < hdr->n_region; i++) { region =3D (const void *)((const u8 *)hdr - (hdr->n_region - i) * sizeof(*region)); len =3D le32_to_cpu(region->len); /* check if we have valid buffer size */ - if (offset + len > fw->size) { + if (len > fw_data_len - offset) { dev_err(mdev->dev, "Invalid firmware region\n"); ret =3D -EINVAL; goto out; @@ -464,8 +473,19 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name) if (!clc_base) goto out; - for (offset =3D 0; offset < len; offset +=3D le32_to_cpu(clc->len)) { + for (offset =3D 0; offset < len; offset +=3D clc_len) { + if (len - offset < sizeof(*clc)) { + ret =3D -EINVAL; + goto out; + } + clc =3D (const struct mt7921_clc *)(clc_base + offset); + clc_len =3D le32_to_cpu(clc->len); + if (clc_len < sizeof(*clc) || clc_len > len - offset || + clc->idx >=3D ARRAY_SIZE(phy->clc)) { + ret =3D -EINVAL; + goto out; + } /* do not init buf again if chip reset triggered */ if (phy->clc[clc->idx]) @@ -477,7 +497,7 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name) continue; phy->clc[clc->idx] =3D devm_kmemdup(mdev->dev, clc, - le32_to_cpu(clc->len), + clc_len, GFP_KERNEL); if (!phy->clc[clc->idx]) {