{
  "schema_version": "1.6.1",
  "id": "RPI-CVE-2024-39503",
  "modified": "2026-10-09T11:39:44Z",
  "upstream": [
    "CVE-2024-39503"
  ],
  "published": "2024-07-12T12:21:19Z",
  "summary": "netfilter: ipset: Fix race between namespace cleanup and gc in the list:set type",
  "details": "In the Linux kernel, the following vulnerability has been resolved:\n\nnetfilter: ipset: Fix race between namespace cleanup and gc in the list:set type\n\nLion Ackermann reported that there is a race condition between namespace cleanup\nin ipset and the garbage collection of the list:set type. The namespace\ncleanup can destroy the list:set type of sets while the gc of the set type is\nwaiting to run in rcu cleanup. The latter uses data from the destroyed set which\nthus leads use after free. The patch contains the following parts:\n\n- When destroying all sets, first remove the garbage collectors, then wait\n  if needed and then destroy the sets.\n- Fix the badly ordered \"wait then remove gc\" for the destroy a single set\n  case.\n- Fix the missing rcu locking in the list:set type in the userspace test\n  case.\n- Use proper RCU list handlings in the list:set type.\n\nThe patch depends on c1193d9bbbd3 (netfilter: ipset: Add list flush to cancel_gc).",
  "severity": [
    {
      "type": "CVSS_V3",
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
    }
  ],
  "affected": [
    {
      "package": {
        "ecosystem": "Raspberry Pi OS:12",
        "name": "linux"
      },
      "versions": [
        "1:6.6.20-1+rpt1",
        "1:6.6.28-1+rpt1",
        "1:6.6.31-1+rpt1"
      ],
      "ecosystem_specific": {
        "binaries": [
          {
            "binary_name": "linux-image-6.6.20+rpt-rpi-2712",
            "binary_version": "1:6.6.20-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.20+rpt-rpi-v6",
            "binary_version": "1:6.6.20-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.20+rpt-rpi-v7",
            "binary_version": "1:6.6.20-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.20+rpt-rpi-v7l",
            "binary_version": "1:6.6.20-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.20+rpt-rpi-v8",
            "binary_version": "1:6.6.20-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.28+rpt-rpi-2712",
            "binary_version": "1:6.6.28-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.28+rpt-rpi-v6",
            "binary_version": "1:6.6.28-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.28+rpt-rpi-v7",
            "binary_version": "1:6.6.28-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.28+rpt-rpi-v7l",
            "binary_version": "1:6.6.28-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.28+rpt-rpi-v8",
            "binary_version": "1:6.6.28-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.31+rpt-rpi-2712",
            "binary_version": "1:6.6.31-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.31+rpt-rpi-v6",
            "binary_version": "1:6.6.31-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.31+rpt-rpi-v7",
            "binary_version": "1:6.6.31-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.31+rpt-rpi-v7l",
            "binary_version": "1:6.6.31-1+rpt1"
          },
          {
            "binary_name": "linux-image-6.6.31+rpt-rpi-v8",
            "binary_version": "1:6.6.31-1+rpt1"
          }
        ]
      },
      "database_specific": {
        "per_version": {
          "1:6.6.20-1+rpt1": {
            "linux_commit": "6f16847710cc0502450788b9f12f0a14d3429668",
            "upstream_version": "6.6.20",
            "assessment": "commit ancestry (strak rule)",
            "upstream_fixed": "6.6.35"
          },
          "1:6.6.28-1+rpt1": {
            "linux_commit": "0c341f47adc3578cd5f817aa20ee2b7f9ae6b23e",
            "upstream_version": "6.6.28",
            "assessment": "commit ancestry (strak rule)",
            "upstream_fixed": "6.6.35"
          },
          "1:6.6.31-1+rpt1": {
            "linux_commit": "c1432b4bae5b6582f4d32ba381459f33c34d1424",
            "upstream_version": "6.6.31",
            "assessment": "commit ancestry (strak rule)",
            "upstream_fixed": "6.6.35"
          }
        }
      }
    }
  ],
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://www.cve.org/CVERecord?id=CVE-2024-39503"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/c0761d1f1ce1d5b85b5e82bbb714df12de1aa8c3"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/93b53c202b51a69e42ca57f5a183f7e008e19f83"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/0f1bb77c6d837c9513943bc7c08f04c5cc5c6568"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/390b353d1a1da3e9c6c0fd14fe650d69063c95d6"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/2ba35b37f780c6410bb4bba9c3072596d8576702"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/90ae20d47de602198eb69e6cd7a3db3420abfc08"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/4e7aaa6b82d63e8ddcbfb56b4fd3d014ca586f10"
    }
  ],
  "database_specific": {
    "source": "https://git.kernel.org/pub/scm/linux/security/vulns.git",
    "upstream_modified": "2026-08-05T11:52:36Z",
    "severity": {
      "source": "kernel CNA",
      "cvss_v3_score": 7.8,
      "cvss_v3_severity": "High",
      "scenario": "AV:L - The vulnerable paths are the ipset nfnetlink command handler (`ip_set_destroy()` via NFNL_SUBSYS_IPSET) and network-namespace teardown (`ip_set_net_exit()`), both of which require local access via a netlink socket or namespace lifecycle. No remote peer data reaches the freed object.\nAC:L - `cancel_gc()` queues `call_rcu(&e->rcu, __list_set_del_rcu)` and `set` is `kfree()`d immediately afterwards, so the callback is guaranteed to dereference freed memory \u2014 the attacker owns both sides (creating the set and issuing destroy/exiting the netns) and can repeat it arbitrarily to win the reclaim. CONFIG_IP_SET is a standard distro module, so no rare configuration is needed.\nPR:L - `nfnetlink_rcv()` checks `netlink_net_capable(skb, CAP_NET_ADMIN)`, which resolves to `ns_capable(net->user_ns, CAP_NET_ADMIN)`, so any unprivileged user gets it with `unshare -Urn`; ipset state is fully per-netns, and namespace exit is itself an unprivileged-user-controlled event.\nUI:N - The attacker performs every step alone \u2014 create the list:set, add a member, then destroy the set or exit the namespace. No victim action is involved.\nS:U - The use-after-free corrupts kernel heap memory within the same kernel security authority; there is no VM, IOMMU, or sandbox boundary crossed.\nC:H - After `struct ip_set` (generic kmalloc-192) is reclaimed and sprayed, `ip_set_ext_destroy()` reads `set->extensions` and `set->offset[IPSET_EXT_ID_COMMENT]` from attacker data, and `ip_set_comment_free()` performs `strlen(c->str)` on the resulting pointer \u2014 an arbitrary kernel read usable for full memory disclosure and KASLR defeat.\nI:H - The same chain yields `kfree_rcu()` on an attacker-chosen address (arbitrary free), an `rcu_assign_pointer(comment->c, NULL)` write, and an arithmetic write into the freed object, giving the write primitives needed for control-flow hijacking and privilege escalation; a stale `module_put()` can additionally leave module text freed under a pending callback.\nA:H - Even unweaponized, the guaranteed use-after-free on `struct ip_set` and the resulting wild `kfree()` cause slab corruption, oops, or kernel panic, and the trigger can be repeated in a loop by any local user."
    }
  }
}
