cve-2024-26921
Vulnerability from cvelistv5
Published
2024-04-18 09:47
Modified
2024-08-02 00:21
Severity
Summary
inet: inet_defrag: prevent sk release while still in use
Impacted products
VendorProduct
LinuxLinux
LinuxLinux
Show details on NVD website


{
  "containers": {
    "adp": [
      {
        "metrics": [
          {
            "other": {
              "content": {
                "id": "CVE-2024-26921",
                "options": [
                  {
                    "Exploitation": "none"
                  },
                  {
                    "Automatable": "yes"
                  },
                  {
                    "Technical Impact": "partial"
                  }
                ],
                "role": "CISA Coordinator",
                "timestamp": "2024-04-18T19:03:24.189248Z",
                "version": "2.0.3"
              },
              "type": "ssvc"
            }
          }
        ],
        "providerMetadata": {
          "dateUpdated": "2024-07-24T15:27:10.496Z",
          "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
          "shortName": "CISA-ADP"
        },
        "title": "CISA ADP Vulnrichment"
      },
      {
        "providerMetadata": {
          "dateUpdated": "2024-08-02T00:21:05.576Z",
          "orgId": "af854a3a-2127-422b-91ae-364da2661108",
          "shortName": "CVE"
        },
        "references": [
          {
            "tags": [
              "x_transferred"
            ],
            "url": "https://git.kernel.org/stable/c/7d0567842b78390dd9b60f00f1d8f838d540e325"
          },
          {
            "tags": [
              "x_transferred"
            ],
            "url": "https://git.kernel.org/stable/c/f4877225313d474659ee53150ccc3d553a978727"
          },
          {
            "tags": [
              "x_transferred"
            ],
            "url": "https://git.kernel.org/stable/c/e09cbe017311508c21e0739e97198a8388b98981"
          },
          {
            "tags": [
              "x_transferred"
            ],
            "url": "https://git.kernel.org/stable/c/18685451fc4e546fc0e718580d32df3c0e5c8272"
          }
        ],
        "title": "CVE Program Container"
      }
    ],
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "Linux",
          "programFiles": [
            "include/linux/skbuff.h",
            "net/ipv4/inet_fragment.c",
            "net/ipv4/ip_fragment.c",
            "net/ipv6/netfilter/nf_conntrack_reasm.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "lessThan": "7d0567842b78",
              "status": "affected",
              "version": "7026b1ddb6b8",
              "versionType": "git"
            },
            {
              "lessThan": "f4877225313d",
              "status": "affected",
              "version": "7026b1ddb6b8",
              "versionType": "git"
            },
            {
              "lessThan": "e09cbe017311",
              "status": "affected",
              "version": "7026b1ddb6b8",
              "versionType": "git"
            },
            {
              "lessThan": "18685451fc4e",
              "status": "affected",
              "version": "7026b1ddb6b8",
              "versionType": "git"
            }
          ]
        },
        {
          "defaultStatus": "affected",
          "product": "Linux",
          "programFiles": [
            "include/linux/skbuff.h",
            "net/ipv4/inet_fragment.c",
            "net/ipv4/ip_fragment.c",
            "net/ipv6/netfilter/nf_conntrack_reasm.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "4.1"
            },
            {
              "lessThan": "4.1",
              "status": "unaffected",
              "version": "0",
              "versionType": "custom"
            },
            {
              "lessThanOrEqual": "6.1.*",
              "status": "unaffected",
              "version": "6.1.85",
              "versionType": "custom"
            },
            {
              "lessThanOrEqual": "6.6.*",
              "status": "unaffected",
              "version": "6.6.26",
              "versionType": "custom"
            },
            {
              "lessThanOrEqual": "6.8.*",
              "status": "unaffected",
              "version": "6.8.5",
              "versionType": "custom"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "6.9",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\ninet: inet_defrag: prevent sk release while still in use\n\nip_local_out() and other functions can pass skb-\u003esk as function argument.\n\nIf the skb is a fragment and reassembly happens before such function call\nreturns, the sk must not be released.\n\nThis affects skb fragments reassembled via netfilter or similar\nmodules, e.g. openvswitch or ct_act.c, when run as part of tx pipeline.\n\nEric Dumazet made an initial analysis of this bug.  Quoting Eric:\n  Calling ip_defrag() in output path is also implying skb_orphan(),\n  which is buggy because output path relies on sk not disappearing.\n\n  A relevant old patch about the issue was :\n  8282f27449bf (\"inet: frag: Always orphan skbs inside ip_defrag()\")\n\n  [..]\n\n  net/ipv4/ip_output.c depends on skb-\u003esk being set, and probably to an\n  inet socket, not an arbitrary one.\n\n  If we orphan the packet in ipvlan, then downstream things like FQ\n  packet scheduler will not work properly.\n\n  We need to change ip_defrag() to only use skb_orphan() when really\n  needed, ie whenever frag_list is going to be used.\n\nEric suggested to stash sk in fragment queue and made an initial patch.\nHowever there is a problem with this:\n\nIf skb is refragmented again right after, ip_do_fragment() will copy\nhead-\u003esk to the new fragments, and sets up destructor to sock_wfree.\nIOW, we have no choice but to fix up sk_wmem accouting to reflect the\nfully reassembled skb, else wmem will underflow.\n\nThis change moves the orphan down into the core, to last possible moment.\nAs ip_defrag_offset is aliased with sk_buff-\u003esk member, we must move the\noffset into the FRAG_CB, else skb-\u003esk gets clobbered.\n\nThis allows to delay the orphaning long enough to learn if the skb has\nto be queued or if the skb is completing the reasm queue.\n\nIn the former case, things work as before, skb is orphaned.  This is\nsafe because skb gets queued/stolen and won\u0027t continue past reasm engine.\n\nIn the latter case, we will steal the skb-\u003esk reference, reattach it to\nthe head skb, and fix up wmem accouting when inet_frag inflates truesize."
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2024-05-29T05:25:03.254Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/7d0567842b78390dd9b60f00f1d8f838d540e325"
        },
        {
          "url": "https://git.kernel.org/stable/c/f4877225313d474659ee53150ccc3d553a978727"
        },
        {
          "url": "https://git.kernel.org/stable/c/e09cbe017311508c21e0739e97198a8388b98981"
        },
        {
          "url": "https://git.kernel.org/stable/c/18685451fc4e546fc0e718580d32df3c0e5c8272"
        }
      ],
      "title": "inet: inet_defrag: prevent sk release while still in use",
      "x_generator": {
        "engine": "bippy-a5840b7849dd"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2024-26921",
    "datePublished": "2024-04-18T09:47:58.632Z",
    "dateReserved": "2024-02-19T14:20:24.194Z",
    "dateUpdated": "2024-08-02T00:21:05.576Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.1",
  "meta": {
    "nvd": "{\"cve\":{\"id\":\"CVE-2024-26921\",\"sourceIdentifier\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"published\":\"2024-04-18T10:15:07.740\",\"lastModified\":\"2024-04-18T13:04:28.900\",\"vulnStatus\":\"Awaiting Analysis\",\"descriptions\":[{\"lang\":\"en\",\"value\":\"In the Linux kernel, the following vulnerability has been resolved:\\n\\ninet: inet_defrag: prevent sk release while still in use\\n\\nip_local_out() and other functions can pass skb-\u003esk as function argument.\\n\\nIf the skb is a fragment and reassembly happens before such function call\\nreturns, the sk must not be released.\\n\\nThis affects skb fragments reassembled via netfilter or similar\\nmodules, e.g. openvswitch or ct_act.c, when run as part of tx pipeline.\\n\\nEric Dumazet made an initial analysis of this bug.  Quoting Eric:\\n  Calling ip_defrag() in output path is also implying skb_orphan(),\\n  which is buggy because output path relies on sk not disappearing.\\n\\n  A relevant old patch about the issue was :\\n  8282f27449bf (\\\"inet: frag: Always orphan skbs inside ip_defrag()\\\")\\n\\n  [..]\\n\\n  net/ipv4/ip_output.c depends on skb-\u003esk being set, and probably to an\\n  inet socket, not an arbitrary one.\\n\\n  If we orphan the packet in ipvlan, then downstream things like FQ\\n  packet scheduler will not work properly.\\n\\n  We need to change ip_defrag() to only use skb_orphan() when really\\n  needed, ie whenever frag_list is going to be used.\\n\\nEric suggested to stash sk in fragment queue and made an initial patch.\\nHowever there is a problem with this:\\n\\nIf skb is refragmented again right after, ip_do_fragment() will copy\\nhead-\u003esk to the new fragments, and sets up destructor to sock_wfree.\\nIOW, we have no choice but to fix up sk_wmem accouting to reflect the\\nfully reassembled skb, else wmem will underflow.\\n\\nThis change moves the orphan down into the core, to last possible moment.\\nAs ip_defrag_offset is aliased with sk_buff-\u003esk member, we must move the\\noffset into the FRAG_CB, else skb-\u003esk gets clobbered.\\n\\nThis allows to delay the orphaning long enough to learn if the skb has\\nto be queued or if the skb is completing the reasm queue.\\n\\nIn the former case, things work as before, skb is orphaned.  This is\\nsafe because skb gets queued/stolen and won\u0027t continue past reasm engine.\\n\\nIn the latter case, we will steal the skb-\u003esk reference, reattach it to\\nthe head skb, and fix up wmem accouting when inet_frag inflates truesize.\"},{\"lang\":\"es\",\"value\":\"En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: inet: inet_defrag: evita la liberaci\u00f3n de sk mientras a\u00fan est\u00e1 en uso ip_local_out() y otras funciones pueden pasar skb-\u0026gt;sk como argumento de funci\u00f3n. Si el skb es un fragmento y el reensamblaje ocurre antes de que regrese dicha llamada a la funci\u00f3n, el sk no debe liberarse. Esto afecta a los fragmentos de skb reensamblados mediante netfilter o m\u00f3dulos similares, por ejemplo, openvswitch o ct_act.c, cuando se ejecutan como parte de la canalizaci\u00f3n tx. Eric Dumazet hizo un an\u00e1lisis inicial de este error. Citando a Eric: Llamar a ip_defrag() en la ruta de salida tambi\u00e9n implica skb_orphan(), lo cual tiene errores porque la ruta de salida depende de que sk no desaparezca. Un parche antiguo relevante sobre el problema era: 8282f27449bf (\\\"inet: frag: Siempre skbs hu\u00e9rfanos dentro de ip_defrag()\\\") [..] net/ipv4/ip_output.c depende de que skb-\u0026gt;sk est\u00e9 configurado, y probablemente en un inet socket, no uno arbitrario. Si dejamos el paquete hu\u00e9rfano en ipvlan, las cosas posteriores como el programador de paquetes FQ no funcionar\u00e1n correctamente. Necesitamos cambiar ip_defrag() para usar skb_orphan() solo cuando sea realmente necesario, es decir, siempre que se vaya a usar frag_list. Eric sugiri\u00f3 guardar sk en la cola de fragmentos e hizo un parche inicial. Sin embargo, hay un problema con esto: si skb se vuelve a fragmentar inmediatamente despu\u00e9s, ip_do_fragment() copiar\u00e1 head-\u0026gt;sk a los nuevos fragmentos y configurar\u00e1 el destructor en sock_wfree. OIA, no tenemos m\u00e1s remedio que arreglar la contabilidad de sk_wmem para reflejar el skb completamente reensamblado; de lo contrario, wmem se desbordar\u00e1. Este cambio mueve al hu\u00e9rfano hacia el n\u00facleo, hasta el \u00faltimo momento posible. Como ip_defrag_offset tiene un alias con el miembro sk_buff-\u0026gt;sk, debemos mover el desplazamiento a FRAG_CB; de lo contrario, skb-\u0026gt;sk ser\u00e1 golpeado. Esto permite retrasar el hu\u00e9rfano el tiempo suficiente para saber si el skb debe estar en cola o si el skb est\u00e1 completando la cola de reasm. En el primer caso, las cosas funcionan como antes, skb queda hu\u00e9rfano. Esto es seguro porque skb se pone en cola/se roba y no contin\u00faa m\u00e1s all\u00e1 del motor de reasm. En el \u00faltimo caso, robaremos la referencia skb-\u0026gt;sk, la volveremos a adjuntar al skb principal y arreglaremos la contabilidad de wmem cuando inet_frag infle el tama\u00f1o verdadero.\"}],\"metrics\":{},\"references\":[{\"url\":\"https://git.kernel.org/stable/c/18685451fc4e546fc0e718580d32df3c0e5c8272\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/7d0567842b78390dd9b60f00f1d8f838d540e325\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/e09cbe017311508c21e0739e97198a8388b98981\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/f4877225313d474659ee53150ccc3d553a978727\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"}]}}"
  }
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading...

Loading...