cve-2024-50200
Vulnerability from cvelistv5
Published
2024-11-08 05:54
Modified
2024-12-19 09:35
Severity ?
Summary
In the Linux kernel, the following vulnerability has been resolved: maple_tree: correct tree corruption on spanning store Patch series "maple_tree: correct tree corruption on spanning store", v3. There has been a nasty yet subtle maple tree corruption bug that appears to have been in existence since the inception of the algorithm. This bug seems far more likely to happen since commit f8d112a4e657 ("mm/mmap: avoid zeroing vma tree in mmap_region()"), which is the point at which reports started to be submitted concerning this bug. We were made definitely aware of the bug thanks to the kind efforts of Bert Karwatzki who helped enormously in my being able to track this down and identify the cause of it. The bug arises when an attempt is made to perform a spanning store across two leaf nodes, where the right leaf node is the rightmost child of the shared parent, AND the store completely consumes the right-mode node. This results in mas_wr_spanning_store() mitakenly duplicating the new and existing entries at the maximum pivot within the range, and thus maple tree corruption. The fix patch corrects this by detecting this scenario and disallowing the mistaken duplicate copy. The fix patch commit message goes into great detail as to how this occurs. This series also includes a test which reliably reproduces the issue, and asserts that the fix works correctly. Bert has kindly tested the fix and confirmed it resolved his issues. Also Mikhail Gavrilov kindly reported what appears to be precisely the same bug, which this fix should also resolve. This patch (of 2): There has been a subtle bug present in the maple tree implementation from its inception. This arises from how stores are performed - when a store occurs, it will overwrite overlapping ranges and adjust the tree as necessary to accommodate this. A range may always ultimately span two leaf nodes. In this instance we walk the two leaf nodes, determine which elements are not overwritten to the left and to the right of the start and end of the ranges respectively and then rebalance the tree to contain these entries and the newly inserted one. This kind of store is dubbed a 'spanning store' and is implemented by mas_wr_spanning_store(). In order to reach this stage, mas_store_gfp() invokes mas_wr_preallocate(), mas_wr_store_type() and mas_wr_walk() in turn to walk the tree and update the object (mas) to traverse to the location where the write should be performed, determining its store type. When a spanning store is required, this function returns false stopping at the parent node which contains the target range, and mas_wr_store_type() marks the mas->store_type as wr_spanning_store to denote this fact. When we go to perform the store in mas_wr_spanning_store(), we first determine the elements AFTER the END of the range we wish to store (that is, to the right of the entry to be inserted) - we do this by walking to the NEXT pivot in the tree (i.e. r_mas.last + 1), starting at the node we have just determined contains the range over which we intend to write. We then turn our attention to the entries to the left of the entry we are inserting, whose state is represented by l_mas, and copy these into a 'big node', which is a special node which contains enough slots to contain two leaf node's worth of data. We then copy the entry we wish to store immediately after this - the copy and the insertion of the new entry is performed by mas_store_b_node(). After this we copy the elements to the right of the end of the range which we are inserting, if we have not exceeded the length of the node (i.e. r_mas.offset <= r_mas.end). Herein lies the bug - under very specific circumstances, this logic can break and corrupt the maple tree. Consider the following tree: Height 0 Root Node / \ pivot = 0xffff / \ pivot = ULONG_MAX / ---truncated---
Impacted products
Vendor Product Version
Linux Linux Version: 6.1
Show details on NVD website


{
  "containers": {
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "Linux",
          "programFiles": [
            "lib/maple_tree.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "lessThan": "7c7874977da9e47ca0f53d8b9a5b17385fed83f2",
              "status": "affected",
              "version": "54a611b605901c7d5d05b6b8f5d04a6ceb0962aa",
              "versionType": "git"
            },
            {
              "lessThan": "677f1df179cb68c12ddf7707ec325eb50e99c7d9",
              "status": "affected",
              "version": "54a611b605901c7d5d05b6b8f5d04a6ceb0962aa",
              "versionType": "git"
            },
            {
              "lessThan": "982dd0d26d1f015ed34866579480d2be5250b0ef",
              "status": "affected",
              "version": "54a611b605901c7d5d05b6b8f5d04a6ceb0962aa",
              "versionType": "git"
            },
            {
              "lessThan": "bea07fd63192b61209d48cbb81ef474cc3ee4c62",
              "status": "affected",
              "version": "54a611b605901c7d5d05b6b8f5d04a6ceb0962aa",
              "versionType": "git"
            }
          ]
        },
        {
          "defaultStatus": "affected",
          "product": "Linux",
          "programFiles": [
            "lib/maple_tree.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "6.1"
            },
            {
              "lessThan": "6.1",
              "status": "unaffected",
              "version": "0",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.1.*",
              "status": "unaffected",
              "version": "6.1.114",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.6.*",
              "status": "unaffected",
              "version": "6.6.58",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.11.*",
              "status": "unaffected",
              "version": "6.11.5",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "6.12",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nmaple_tree: correct tree corruption on spanning store\n\nPatch series \"maple_tree: correct tree corruption on spanning store\", v3.\n\nThere has been a nasty yet subtle maple tree corruption bug that appears\nto have been in existence since the inception of the algorithm.\n\nThis bug seems far more likely to happen since commit f8d112a4e657\n(\"mm/mmap: avoid zeroing vma tree in mmap_region()\"), which is the point\nat which reports started to be submitted concerning this bug.\n\nWe were made definitely aware of the bug thanks to the kind efforts of\nBert Karwatzki who helped enormously in my being able to track this down\nand identify the cause of it.\n\nThe bug arises when an attempt is made to perform a spanning store across\ntwo leaf nodes, where the right leaf node is the rightmost child of the\nshared parent, AND the store completely consumes the right-mode node.\n\nThis results in mas_wr_spanning_store() mitakenly duplicating the new and\nexisting entries at the maximum pivot within the range, and thus maple\ntree corruption.\n\nThe fix patch corrects this by detecting this scenario and disallowing the\nmistaken duplicate copy.\n\nThe fix patch commit message goes into great detail as to how this occurs.\n\nThis series also includes a test which reliably reproduces the issue, and\nasserts that the fix works correctly.\n\nBert has kindly tested the fix and confirmed it resolved his issues.  Also\nMikhail Gavrilov kindly reported what appears to be precisely the same\nbug, which this fix should also resolve.\n\n\nThis patch (of 2):\n\nThere has been a subtle bug present in the maple tree implementation from\nits inception.\n\nThis arises from how stores are performed - when a store occurs, it will\noverwrite overlapping ranges and adjust the tree as necessary to\naccommodate this.\n\nA range may always ultimately span two leaf nodes.  In this instance we\nwalk the two leaf nodes, determine which elements are not overwritten to\nthe left and to the right of the start and end of the ranges respectively\nand then rebalance the tree to contain these entries and the newly\ninserted one.\n\nThis kind of store is dubbed a \u0027spanning store\u0027 and is implemented by\nmas_wr_spanning_store().\n\nIn order to reach this stage, mas_store_gfp() invokes\nmas_wr_preallocate(), mas_wr_store_type() and mas_wr_walk() in turn to\nwalk the tree and update the object (mas) to traverse to the location\nwhere the write should be performed, determining its store type.\n\nWhen a spanning store is required, this function returns false stopping at\nthe parent node which contains the target range, and mas_wr_store_type()\nmarks the mas-\u003estore_type as wr_spanning_store to denote this fact.\n\nWhen we go to perform the store in mas_wr_spanning_store(), we first\ndetermine the elements AFTER the END of the range we wish to store (that\nis, to the right of the entry to be inserted) - we do this by walking to\nthe NEXT pivot in the tree (i.e.  r_mas.last + 1), starting at the node we\nhave just determined contains the range over which we intend to write.\n\nWe then turn our attention to the entries to the left of the entry we are\ninserting, whose state is represented by l_mas, and copy these into a \u0027big\nnode\u0027, which is a special node which contains enough slots to contain two\nleaf node\u0027s worth of data.\n\nWe then copy the entry we wish to store immediately after this - the copy\nand the insertion of the new entry is performed by mas_store_b_node().\n\nAfter this we copy the elements to the right of the end of the range which\nwe are inserting, if we have not exceeded the length of the node (i.e. \nr_mas.offset \u003c= r_mas.end).\n\nHerein lies the bug - under very specific circumstances, this logic can\nbreak and corrupt the maple tree.\n\nConsider the following tree:\n\nHeight\n  0                             Root Node\n                                 /      \\\n                 pivot = 0xffff /        \\ pivot = ULONG_MAX\n                               /          \n---truncated---"
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2024-12-19T09:35:19.093Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/7c7874977da9e47ca0f53d8b9a5b17385fed83f2"
        },
        {
          "url": "https://git.kernel.org/stable/c/677f1df179cb68c12ddf7707ec325eb50e99c7d9"
        },
        {
          "url": "https://git.kernel.org/stable/c/982dd0d26d1f015ed34866579480d2be5250b0ef"
        },
        {
          "url": "https://git.kernel.org/stable/c/bea07fd63192b61209d48cbb81ef474cc3ee4c62"
        }
      ],
      "title": "maple_tree: correct tree corruption on spanning store",
      "x_generator": {
        "engine": "bippy-5f407fcff5a0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2024-50200",
    "datePublished": "2024-11-08T05:54:14.167Z",
    "dateReserved": "2024-10-21T19:36:19.969Z",
    "dateUpdated": "2024-12-19T09:35:19.093Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.1",
  "meta": {
    "nvd": "{\"cve\":{\"id\":\"CVE-2024-50200\",\"sourceIdentifier\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"published\":\"2024-11-08T06:15:16.593\",\"lastModified\":\"2024-11-08T19:01:03.880\",\"vulnStatus\":\"Awaiting Analysis\",\"cveTags\":[],\"descriptions\":[{\"lang\":\"en\",\"value\":\"In the Linux kernel, the following vulnerability has been resolved:\\n\\nmaple_tree: correct tree corruption on spanning store\\n\\nPatch series \\\"maple_tree: correct tree corruption on spanning store\\\", v3.\\n\\nThere has been a nasty yet subtle maple tree corruption bug that appears\\nto have been in existence since the inception of the algorithm.\\n\\nThis bug seems far more likely to happen since commit f8d112a4e657\\n(\\\"mm/mmap: avoid zeroing vma tree in mmap_region()\\\"), which is the point\\nat which reports started to be submitted concerning this bug.\\n\\nWe were made definitely aware of the bug thanks to the kind efforts of\\nBert Karwatzki who helped enormously in my being able to track this down\\nand identify the cause of it.\\n\\nThe bug arises when an attempt is made to perform a spanning store across\\ntwo leaf nodes, where the right leaf node is the rightmost child of the\\nshared parent, AND the store completely consumes the right-mode node.\\n\\nThis results in mas_wr_spanning_store() mitakenly duplicating the new and\\nexisting entries at the maximum pivot within the range, and thus maple\\ntree corruption.\\n\\nThe fix patch corrects this by detecting this scenario and disallowing the\\nmistaken duplicate copy.\\n\\nThe fix patch commit message goes into great detail as to how this occurs.\\n\\nThis series also includes a test which reliably reproduces the issue, and\\nasserts that the fix works correctly.\\n\\nBert has kindly tested the fix and confirmed it resolved his issues.  Also\\nMikhail Gavrilov kindly reported what appears to be precisely the same\\nbug, which this fix should also resolve.\\n\\n\\nThis patch (of 2):\\n\\nThere has been a subtle bug present in the maple tree implementation from\\nits inception.\\n\\nThis arises from how stores are performed - when a store occurs, it will\\noverwrite overlapping ranges and adjust the tree as necessary to\\naccommodate this.\\n\\nA range may always ultimately span two leaf nodes.  In this instance we\\nwalk the two leaf nodes, determine which elements are not overwritten to\\nthe left and to the right of the start and end of the ranges respectively\\nand then rebalance the tree to contain these entries and the newly\\ninserted one.\\n\\nThis kind of store is dubbed a \u0027spanning store\u0027 and is implemented by\\nmas_wr_spanning_store().\\n\\nIn order to reach this stage, mas_store_gfp() invokes\\nmas_wr_preallocate(), mas_wr_store_type() and mas_wr_walk() in turn to\\nwalk the tree and update the object (mas) to traverse to the location\\nwhere the write should be performed, determining its store type.\\n\\nWhen a spanning store is required, this function returns false stopping at\\nthe parent node which contains the target range, and mas_wr_store_type()\\nmarks the mas-\u003estore_type as wr_spanning_store to denote this fact.\\n\\nWhen we go to perform the store in mas_wr_spanning_store(), we first\\ndetermine the elements AFTER the END of the range we wish to store (that\\nis, to the right of the entry to be inserted) - we do this by walking to\\nthe NEXT pivot in the tree (i.e.  r_mas.last + 1), starting at the node we\\nhave just determined contains the range over which we intend to write.\\n\\nWe then turn our attention to the entries to the left of the entry we are\\ninserting, whose state is represented by l_mas, and copy these into a \u0027big\\nnode\u0027, which is a special node which contains enough slots to contain two\\nleaf node\u0027s worth of data.\\n\\nWe then copy the entry we wish to store immediately after this - the copy\\nand the insertion of the new entry is performed by mas_store_b_node().\\n\\nAfter this we copy the elements to the right of the end of the range which\\nwe are inserting, if we have not exceeded the length of the node (i.e. \\nr_mas.offset \u003c= r_mas.end).\\n\\nHerein lies the bug - under very specific circumstances, this logic can\\nbreak and corrupt the maple tree.\\n\\nConsider the following tree:\\n\\nHeight\\n  0                             Root Node\\n                                 /      \\\\\\n                 pivot = 0xffff /        \\\\ pivot = ULONG_MAX\\n                               /          \\n---truncated---\"},{\"lang\":\"es\",\"value\":\"En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: maple_tree: corregir la corrupci\u00f3n del \u00e1rbol en el almac\u00e9n de expansi\u00f3n Serie de parches \\\"maple_tree: corregir la corrupci\u00f3n del \u00e1rbol en el almac\u00e9n de expansi\u00f3n\\\", v3. Ha habido un error de corrupci\u00f3n del \u00e1rbol de maple desagradable pero sutil que parece haber existido desde el inicio del algoritmo. Este error parece mucho m\u00e1s probable que ocurra desde el commit f8d112a4e657 (\\\"mm/mmap: evitar poner a cero el \u00e1rbol vma en mmap_region()\\\"), que es el punto en el que comenzaron a enviarse informes sobre este error. Nos enteramos definitivamente del error gracias a los amables esfuerzos de Bert Karwatzki, quien me ayud\u00f3 enormemente a poder rastrearlo e identificar la causa. El error surge cuando se intenta realizar un almacenamiento de expansi\u00f3n en dos nodos de hoja, donde el nodo de hoja derecho es el hijo m\u00e1s a la derecha del padre compartido, y el almacenamiento consume por completo el nodo de modo derecho. Esto da como resultado que mas_wr_spanning_store() duplique por error las entradas nuevas y existentes en el pivote m\u00e1ximo dentro del rango, y por lo tanto la corrupci\u00f3n del \u00e1rbol de maple. El parche de correcci\u00f3n corrige esto detectando este escenario y no permitiendo la copia duplicada err\u00f3nea. El mensaje de confirmaci\u00f3n del parche de correcci\u00f3n detalla en gran medida c\u00f3mo ocurre esto. Esta serie tambi\u00e9n incluye una prueba que reproduce el problema de manera confiable y afirma que la correcci\u00f3n funciona correctamente. Bert ha probado amablemente la correcci\u00f3n y confirm\u00f3 que resolvi\u00f3 sus problemas. Adem\u00e1s, Mikhail Gavrilov inform\u00f3 amablemente lo que parece ser exactamente el mismo error, que esta correcci\u00f3n tambi\u00e9n deber\u00eda resolver. Este parche (de 2): Ha habido un error sutil presente en la implementaci\u00f3n del \u00e1rbol de maple desde su inicio. Esto surge de c\u00f3mo se realizan los almacenamientos: cuando se produce un almacenamiento, sobrescribir\u00e1 los rangos superpuestos y ajustar\u00e1 el \u00e1rbol seg\u00fan sea necesario para adaptarse a esto. Un rango siempre puede abarcar en \u00faltima instancia dos nodos de hoja. En este caso, recorremos los dos nodos de hoja, determinamos qu\u00e9 elementos no se sobrescriben a la izquierda y a la derecha del inicio y el final de los rangos respectivamente y luego reequilibramos el \u00e1rbol para que contenga estas entradas y la reci\u00e9n insertada. Este tipo de almacenamiento se denomina \\\"almac\u00e9n de expansi\u00f3n\\\" y se implementa mediante mas_wr_spanning_store(). Para llegar a esta etapa, mas_store_gfp() invoca a mas_wr_preallocate(), mas_wr_store_type() y mas_wr_walk() a su vez para recorrer el \u00e1rbol y actualizar el objeto (mas) para atravesar la ubicaci\u00f3n donde se debe realizar la escritura, determinando su tipo de almacenamiento. Cuando se requiere un almacenamiento de expansi\u00f3n, esta funci\u00f3n devuelve falso y se detiene en el nodo principal que contiene el rango de destino, y mas_wr_store_type() marca mas-\u0026gt;store_type como wr_spanning_store para denotar este hecho. Cuando vamos a realizar el almacenamiento en mas_wr_spanning_store(), primero determinamos los elementos DESPU\u00c9S del FINAL del rango que deseamos almacenar (es decir, a la derecha de la entrada que se insertar\u00e1); lo hacemos caminando hasta el SIGUIENTE pivote en el \u00e1rbol (es decir, r_mas.last + 1), comenzando en el nodo que acabamos de determinar que contiene el rango sobre el que pretendemos escribir. Luego dirigimos nuestra atenci\u00f3n a las entradas a la izquierda de la entrada que estamos insertando, cuyo estado est\u00e1 representado por l_mas, y las copiamos en un \\\"nodo grande\\\", que es un nodo especial que contiene suficientes ranuras para contener los datos de dos nodos hoja. Luego copiamos la entrada que deseamos almacenar inmediatamente despu\u00e9s de esto; la copia y la inserci\u00f3n de la nueva entrada se realiza mediante mas_store_b_node(). Despu\u00e9s de esto, copiamos los elementos a la derecha del final del rango que estamos insertando, si no hemos excedido la longitud del nodo (es decir, r_mas.offset \u0026lt;= r_mas.end).  ---truncado---\"}],\"metrics\":{},\"references\":[{\"url\":\"https://git.kernel.org/stable/c/677f1df179cb68c12ddf7707ec325eb50e99c7d9\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/7c7874977da9e47ca0f53d8b9a5b17385fed83f2\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/982dd0d26d1f015ed34866579480d2be5250b0ef\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/bea07fd63192b61209d48cbb81ef474cc3ee4c62\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"}]}}"
  }
}


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.
  • 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.