CVE-2025-21970 (GCVE-0-2025-21970)
Vulnerability from cvelistv5
Published
2025-04-01 15:47
Modified
2026-08-05 11:55
Summary
In the Linux kernel, the following vulnerability has been resolved: net/mlx5: Bridge, fix the crash caused by LAG state check When removing LAG device from bridge, NETDEV_CHANGEUPPER event is triggered. Driver finds the lower devices (PFs) to flush all the offloaded entries. And mlx5_lag_is_shared_fdb is checked, it returns false if one of PF is unloaded. In such case, mlx5_esw_bridge_lag_rep_get() and its caller return NULL, instead of the alive PF, and the flush is skipped. Besides, the bridge fdb entry's lastuse is updated in mlx5 bridge event handler. But this SWITCHDEV_FDB_ADD_TO_BRIDGE event can be ignored in this case because the upper interface for bond is deleted, and the entry will never be aged because lastuse is never updated. To make things worse, as the entry is alive, mlx5 bridge workqueue keeps sending that event, which is then handled by kernel bridge notifier. It causes the following crash when accessing the passed bond netdev which is already destroyed. To fix this issue, remove such checks. LAG state is already checked in commit 15f8f168952f ("net/mlx5: Bridge, verify LAG state when adding bond to bridge"), driver still need to skip offload if LAG becomes invalid state after initialization. Oops: stack segment: 0000 [#1] SMP CPU: 3 UID: 0 PID: 23695 Comm: kworker/u40:3 Tainted: G OE 6.11.0_mlnx #1 Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 Workqueue: mlx5_bridge_wq mlx5_esw_bridge_update_work [mlx5_core] RIP: 0010:br_switchdev_event+0x2c/0x110 [bridge] Code: 44 00 00 48 8b 02 48 f7 00 00 02 00 00 74 69 41 54 55 53 48 83 ec 08 48 8b a8 08 01 00 00 48 85 ed 74 4a 48 83 fe 02 48 89 d3 <4c> 8b 65 00 74 23 76 49 48 83 fe 05 74 7e 48 83 fe 06 75 2f 0f b7 RSP: 0018:ffffc900092cfda0 EFLAGS: 00010297 RAX: ffff888123bfe000 RBX: ffffc900092cfe08 RCX: 00000000ffffffff RDX: ffffc900092cfe08 RSI: 0000000000000001 RDI: ffffffffa0c585f0 RBP: 6669746f6e690a30 R08: 0000000000000000 R09: ffff888123ae92c8 R10: 0000000000000000 R11: fefefefefefefeff R12: ffff888123ae9c60 R13: 0000000000000001 R14: ffffc900092cfe08 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff88852c980000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f15914c8734 CR3: 0000000002830005 CR4: 0000000000770ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <TASK> ? __die_body+0x1a/0x60 ? die+0x38/0x60 ? do_trap+0x10b/0x120 ? do_error_trap+0x64/0xa0 ? exc_stack_segment+0x33/0x50 ? asm_exc_stack_segment+0x22/0x30 ? br_switchdev_event+0x2c/0x110 [bridge] ? sched_balance_newidle.isra.149+0x248/0x390 notifier_call_chain+0x4b/0xa0 atomic_notifier_call_chain+0x16/0x20 mlx5_esw_bridge_update+0xec/0x170 [mlx5_core] mlx5_esw_bridge_update_work+0x19/0x40 [mlx5_core] process_scheduled_works+0x81/0x390 worker_thread+0x106/0x250 ? bh_worker+0x110/0x110 kthread+0xb7/0xe0 ? kthread_park+0x80/0x80 ret_from_fork+0x2d/0x50 ? kthread_park+0x80/0x80 ret_from_fork_asm+0x11/0x20 </TASK>
Impacted products
Vendor Product Version
Linux Linux Version: ff9b7521468bc2909293c1cda66a245a49688f6f
Version: ff9b7521468bc2909293c1cda66a245a49688f6f
Version: ff9b7521468bc2909293c1cda66a245a49688f6f
Version: ff9b7521468bc2909293c1cda66a245a49688f6f
Version: ff9b7521468bc2909293c1cda66a245a49688f6f
Version: ff9b7521468bc2909293c1cda66a245a49688f6f
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "adp": [
      {
        "providerMetadata": {
          "dateUpdated": "2025-11-03T19:40:11.287Z",
          "orgId": "af854a3a-2127-422b-91ae-364da2661108",
          "shortName": "CVE"
        },
        "references": [
          {
            "url": "https://lists.debian.org/debian-lts-announce/2025/05/msg00045.html"
          }
        ],
        "title": "CVE Program Container"
      }
    ],
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "Linux",
          "programFiles": [
            "drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "lessThan": "f90c4d6572488e2bad38cca00f1c59174a538a1a",
              "status": "affected",
              "version": "ff9b7521468bc2909293c1cda66a245a49688f6f",
              "versionType": "git"
            },
            {
              "lessThan": "86ff45f5f61ae1d0d17f0f6d8797b052eacfd8f1",
              "status": "affected",
              "version": "ff9b7521468bc2909293c1cda66a245a49688f6f",
              "versionType": "git"
            },
            {
              "lessThan": "bd7e3a42800743a7748c83243e4cafc1b995d4c4",
              "status": "affected",
              "version": "ff9b7521468bc2909293c1cda66a245a49688f6f",
              "versionType": "git"
            },
            {
              "lessThan": "f7bf259a04271165ae667ad21cfc60c6413f25ca",
              "status": "affected",
              "version": "ff9b7521468bc2909293c1cda66a245a49688f6f",
              "versionType": "git"
            },
            {
              "lessThan": "5dd8bf6ab1d6db40f5d09603759fa88caec19e7f",
              "status": "affected",
              "version": "ff9b7521468bc2909293c1cda66a245a49688f6f",
              "versionType": "git"
            },
            {
              "lessThan": "4b8eeed4fb105770ce6dc84a2c6ef953c7b71cbb",
              "status": "affected",
              "version": "ff9b7521468bc2909293c1cda66a245a49688f6f",
              "versionType": "git"
            }
          ]
        },
        {
          "defaultStatus": "affected",
          "product": "Linux",
          "programFiles": [
            "drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "5.15"
            },
            {
              "lessThan": "5.15",
              "status": "unaffected",
              "version": "0",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "5.15.*",
              "status": "unaffected",
              "version": "5.15.180",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.1.*",
              "status": "unaffected",
              "version": "6.1.132",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.6.*",
              "status": "unaffected",
              "version": "6.6.84",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.12.*",
              "status": "unaffected",
              "version": "6.12.20",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.13.*",
              "status": "unaffected",
              "version": "6.13.8",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "6.14",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "5.15.180",
                  "versionStartIncluding": "5.15",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.1.132",
                  "versionStartIncluding": "5.15",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.6.84",
                  "versionStartIncluding": "5.15",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.12.20",
                  "versionStartIncluding": "5.15",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.13.8",
                  "versionStartIncluding": "5.15",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.14",
                  "versionStartIncluding": "5.15",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nnet/mlx5: Bridge, fix the crash caused by LAG state check\n\nWhen removing LAG device from bridge, NETDEV_CHANGEUPPER event is\ntriggered. Driver finds the lower devices (PFs) to flush all the\noffloaded entries. And mlx5_lag_is_shared_fdb is checked, it returns\nfalse if one of PF is unloaded. In such case,\nmlx5_esw_bridge_lag_rep_get() and its caller return NULL, instead of\nthe alive PF, and the flush is skipped.\n\nBesides, the bridge fdb entry\u0027s lastuse is updated in mlx5 bridge\nevent handler. But this SWITCHDEV_FDB_ADD_TO_BRIDGE event can be\nignored in this case because the upper interface for bond is deleted,\nand the entry will never be aged because lastuse is never updated.\n\nTo make things worse, as the entry is alive, mlx5 bridge workqueue\nkeeps sending that event, which is then handled by kernel bridge\nnotifier. It causes the following crash when accessing the passed bond\nnetdev which is already destroyed.\n\nTo fix this issue, remove such checks. LAG state is already checked in\ncommit 15f8f168952f (\"net/mlx5: Bridge, verify LAG state when adding\nbond to bridge\"), driver still need to skip offload if LAG becomes\ninvalid state after initialization.\n\n Oops: stack segment: 0000 [#1] SMP\n CPU: 3 UID: 0 PID: 23695 Comm: kworker/u40:3 Tainted: G           OE      6.11.0_mlnx #1\n Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE\n Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014\n Workqueue: mlx5_bridge_wq mlx5_esw_bridge_update_work [mlx5_core]\n RIP: 0010:br_switchdev_event+0x2c/0x110 [bridge]\n Code: 44 00 00 48 8b 02 48 f7 00 00 02 00 00 74 69 41 54 55 53 48 83 ec 08 48 8b a8 08 01 00 00 48 85 ed 74 4a 48 83 fe 02 48 89 d3 \u003c4c\u003e 8b 65 00 74 23 76 49 48 83 fe 05 74 7e 48 83 fe 06 75 2f 0f b7\n RSP: 0018:ffffc900092cfda0 EFLAGS: 00010297\n RAX: ffff888123bfe000 RBX: ffffc900092cfe08 RCX: 00000000ffffffff\n RDX: ffffc900092cfe08 RSI: 0000000000000001 RDI: ffffffffa0c585f0\n RBP: 6669746f6e690a30 R08: 0000000000000000 R09: ffff888123ae92c8\n R10: 0000000000000000 R11: fefefefefefefeff R12: ffff888123ae9c60\n R13: 0000000000000001 R14: ffffc900092cfe08 R15: 0000000000000000\n FS:  0000000000000000(0000) GS:ffff88852c980000(0000) knlGS:0000000000000000\n CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033\n CR2: 00007f15914c8734 CR3: 0000000002830005 CR4: 0000000000770ef0\n DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000\n DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400\n PKRU: 55555554\n Call Trace:\n  \u003cTASK\u003e\n  ? __die_body+0x1a/0x60\n  ? die+0x38/0x60\n  ? do_trap+0x10b/0x120\n  ? do_error_trap+0x64/0xa0\n  ? exc_stack_segment+0x33/0x50\n  ? asm_exc_stack_segment+0x22/0x30\n  ? br_switchdev_event+0x2c/0x110 [bridge]\n  ? sched_balance_newidle.isra.149+0x248/0x390\n  notifier_call_chain+0x4b/0xa0\n  atomic_notifier_call_chain+0x16/0x20\n  mlx5_esw_bridge_update+0xec/0x170 [mlx5_core]\n  mlx5_esw_bridge_update_work+0x19/0x40 [mlx5_core]\n  process_scheduled_works+0x81/0x390\n  worker_thread+0x106/0x250\n  ? bh_worker+0x110/0x110\n  kthread+0xb7/0xe0\n  ? kthread_park+0x80/0x80\n  ret_from_fork+0x2d/0x50\n  ? kthread_park+0x80/0x80\n  ret_from_fork_asm+0x11/0x20\n  \u003c/TASK\u003e"
        }
      ],
      "metrics": [
        {
          "cvssV3_1": {
            "baseScore": 7.8,
            "baseSeverity": "HIGH",
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
            "version": "3.1"
          },
          "scenarios": [
            {
              "lang": "en",
              "value": "AV:L - The dangling state is created by local network configuration (rtnetlink bond/bridge changes plus mlx5 PF unload) and the UAF is dereferenced by a local kernel workqueue; no remote packet can reach or trigger the vulnerable path. Remote traffic only populates FDB entries, it cannot cause the missed flush.\nAC:L - There is no race to win \u2014 once the LAG loses shared-FDB state and the bond is unlinked from the bridge, the cleanup skip is deterministic and the freed netdev is dereferenced every 1000 ms by mlx5_esw_bridge_update_work, giving an attacker unlimited, repeating reclaim attempts. Heap spraying to occupy the freed net_device allocation is reliable under these repeated triggers.\nPR:L - Establishing the switchdev/LAG/bridge topology needs CAP_NET_ADMIN in the initial namespace, but that state is produced by ordinary operations (driver/firmware reload followed by bridge teardown), after which the use-after-free re-fires automatically every second. An unprivileged local user needs no privileges of their own to reclaim the freed net_device slab and control the dereferenced rx_handler_data pointer.\nUI:N - No victim action is required; the periodic mlx5_bridge_wq delayed work re-dereferences the freed netdev on its own once the stale FDB entries exist. The entries never age out because lastuse is never updated.\nS:U - The corruption and its consequences are confined to the kernel\u0027s own security authority \u2014 no VM, IOMMU, or sandbox boundary is crossed. Attacker and impacted component are both the host kernel.\nC:H - This is a use-after-free on a freed struct net_device: br_switchdev_event() reads dev-\u003epriv_flags and dev-\u003erx_handler_data from reclaimed memory and follows the resulting pointer, so an attacker controlling the reclaiming allocation obtains an arbitrary kernel read primitive. The bridge FDB lookup path then exposes that memory to further disclosure.\nI:H - The attacker-controlled value read from the freed netdev is passed as struct net_bridge_port */struct net_bridge * into br_fdb_external_learn_add(), which performs rhashtable lookups and insertions through those pointers, yielding a controlled kernel write and control-flow hijack potential. Use-after-free of a netdev with a repeating trigger is a strong heap-spray primitive.\nA:H - The commit documents a reproducible kernel oops (\"stack segment\" fault in br_switchdev_event) from the mlx5_bridge_wq worker, and because the stale entries never age out the crash path is re-entered every second. Any such oops in a workqueue context is a full denial of service."
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-08-05T11:55:45.446Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/f90c4d6572488e2bad38cca00f1c59174a538a1a"
        },
        {
          "url": "https://git.kernel.org/stable/c/86ff45f5f61ae1d0d17f0f6d8797b052eacfd8f1"
        },
        {
          "url": "https://git.kernel.org/stable/c/bd7e3a42800743a7748c83243e4cafc1b995d4c4"
        },
        {
          "url": "https://git.kernel.org/stable/c/f7bf259a04271165ae667ad21cfc60c6413f25ca"
        },
        {
          "url": "https://git.kernel.org/stable/c/5dd8bf6ab1d6db40f5d09603759fa88caec19e7f"
        },
        {
          "url": "https://git.kernel.org/stable/c/4b8eeed4fb105770ce6dc84a2c6ef953c7b71cbb"
        }
      ],
      "title": "net/mlx5: Bridge, fix the crash caused by LAG state check",
      "x_generator": {
        "engine": "bippy-1.2.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2025-21970",
    "datePublished": "2025-04-01T15:47:03.912Z",
    "dateReserved": "2024-12-29T08:45:45.797Z",
    "dateUpdated": "2026-08-05T11:55:45.446Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
  • Confirmed: The vulnerability is confirmed from an analyst perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
  • Patched: This vulnerability was successfully patched by the user reporting the sighting.
  • Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
  • Not confirmed: The user expresses doubt about the veracity of the vulnerability.
  • Not patched: This vulnerability was not successfully patched by the user reporting the sighting.


Loading…

Loading…