cve-2021-46957
Vulnerability from cvelistv5
Published
2024-02-27 18:46
Modified
2024-08-04 05:17
Severity
Summary
riscv/kprobe: fix kernel panic when invoking sys_read traced by kprobe
Impacted products
VendorProduct
LinuxLinux
LinuxLinux
Show details on NVD website


{
  "containers": {
    "adp": [
      {
        "metrics": [
          {
            "other": {
              "content": {
                "id": "CVE-2021-46957",
                "options": [
                  {
                    "Exploitation": "none"
                  },
                  {
                    "Automatable": "no"
                  },
                  {
                    "Technical Impact": "partial"
                  }
                ],
                "role": "CISA Coordinator",
                "timestamp": "2024-02-28T19:51:51.883818Z",
                "version": "2.0.3"
              },
              "type": "ssvc"
            }
          }
        ],
        "providerMetadata": {
          "dateUpdated": "2024-06-04T17:13:06.872Z",
          "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
          "shortName": "CISA-ADP"
        },
        "title": "CISA ADP Vulnrichment"
      },
      {
        "providerMetadata": {
          "dateUpdated": "2024-08-04T05:17:43.012Z",
          "orgId": "af854a3a-2127-422b-91ae-364da2661108",
          "shortName": "CVE"
        },
        "references": [
          {
            "tags": [
              "x_transferred"
            ],
            "url": "https://git.kernel.org/stable/c/fd0f06590d35c99f98d12c7984897ec4201a6263"
          },
          {
            "tags": [
              "x_transferred"
            ],
            "url": "https://git.kernel.org/stable/c/b1ebaa0e1318494a7637099a26add50509e37964"
          }
        ],
        "title": "CVE Program Container"
      }
    ],
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "Linux",
          "programFiles": [
            "arch/riscv/kernel/probes/kprobes.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "lessThan": "fd0f06590d35",
              "status": "affected",
              "version": "c22b0bcb1dd0",
              "versionType": "git"
            },
            {
              "lessThan": "b1ebaa0e1318",
              "status": "affected",
              "version": "c22b0bcb1dd0",
              "versionType": "git"
            }
          ]
        },
        {
          "defaultStatus": "affected",
          "product": "Linux",
          "programFiles": [
            "arch/riscv/kernel/probes/kprobes.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "5.12"
            },
            {
              "lessThan": "5.12",
              "status": "unaffected",
              "version": "0",
              "versionType": "custom"
            },
            {
              "lessThanOrEqual": "5.12.*",
              "status": "unaffected",
              "version": "5.12.3",
              "versionType": "custom"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "5.13",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nriscv/kprobe: fix kernel panic when invoking sys_read traced by kprobe\n\nThe execution of sys_read end up hitting a BUG_ON() in __find_get_block\nafter installing kprobe at sys_read, the BUG message like the following:\n\n[   65.708663] ------------[ cut here ]------------\n[   65.709987] kernel BUG at fs/buffer.c:1251!\n[   65.711283] Kernel BUG [#1]\n[   65.712032] Modules linked in:\n[   65.712925] CPU: 0 PID: 51 Comm: sh Not tainted 5.12.0-rc4 #1\n[   65.714407] Hardware name: riscv-virtio,qemu (DT)\n[   65.715696] epc : __find_get_block+0x218/0x2c8\n[   65.716835]  ra : __getblk_gfp+0x1c/0x4a\n[   65.717831] epc : ffffffe00019f11e ra : ffffffe00019f56a sp : ffffffe002437930\n[   65.719553]  gp : ffffffe000f06030 tp : ffffffe0015abc00 t0 : ffffffe00191e038\n[   65.721290]  t1 : ffffffe00191e038 t2 : 000000000000000a s0 : ffffffe002437960\n[   65.723051]  s1 : ffffffe00160ad00 a0 : ffffffe00160ad00 a1 : 000000000000012a\n[   65.724772]  a2 : 0000000000000400 a3 : 0000000000000008 a4 : 0000000000000040\n[   65.726545]  a5 : 0000000000000000 a6 : ffffffe00191e000 a7 : 0000000000000000\n[   65.728308]  s2 : 000000000000012a s3 : 0000000000000400 s4 : 0000000000000008\n[   65.730049]  s5 : 000000000000006c s6 : ffffffe00240f800 s7 : ffffffe000f080a8\n[   65.731802]  s8 : 0000000000000001 s9 : 000000000000012a s10: 0000000000000008\n[   65.733516]  s11: 0000000000000008 t3 : 00000000000003ff t4 : 000000000000000f\n[   65.734434]  t5 : 00000000000003ff t6 : 0000000000040000\n[   65.734613] status: 0000000000000100 badaddr: 0000000000000000 cause: 0000000000000003\n[   65.734901] Call Trace:\n[   65.735076] [\u003cffffffe00019f11e\u003e] __find_get_block+0x218/0x2c8\n[   65.735417] [\u003cffffffe00020017a\u003e] __ext4_get_inode_loc+0xb2/0x2f6\n[   65.735618] [\u003cffffffe000201b6c\u003e] ext4_get_inode_loc+0x3a/0x8a\n[   65.735802] [\u003cffffffe000203380\u003e] ext4_reserve_inode_write+0x2e/0x8c\n[   65.735999] [\u003cffffffe00020357a\u003e] __ext4_mark_inode_dirty+0x4c/0x18e\n[   65.736208] [\u003cffffffe000206bb0\u003e] ext4_dirty_inode+0x46/0x66\n[   65.736387] [\u003cffffffe000192914\u003e] __mark_inode_dirty+0x12c/0x3da\n[   65.736576] [\u003cffffffe000180dd2\u003e] touch_atime+0x146/0x150\n[   65.736748] [\u003cffffffe00010d762\u003e] filemap_read+0x234/0x246\n[   65.736920] [\u003cffffffe00010d834\u003e] generic_file_read_iter+0xc0/0x114\n[   65.737114] [\u003cffffffe0001f5d7a\u003e] ext4_file_read_iter+0x42/0xea\n[   65.737310] [\u003cffffffe000163f2c\u003e] new_sync_read+0xe2/0x15a\n[   65.737483] [\u003cffffffe000165814\u003e] vfs_read+0xca/0xf2\n[   65.737641] [\u003cffffffe000165bae\u003e] ksys_read+0x5e/0xc8\n[   65.737816] [\u003cffffffe000165c26\u003e] sys_read+0xe/0x16\n[   65.737973] [\u003cffffffe000003972\u003e] ret_from_syscall+0x0/0x2\n[   65.738858] ---[ end trace fe93f985456c935d ]---\n\nA simple reproducer looks like:\n\techo \u0027p:myprobe sys_read fd=%a0 buf=%a1 count=%a2\u0027 \u003e /sys/kernel/debug/tracing/kprobe_events\n\techo 1 \u003e /sys/kernel/debug/tracing/events/kprobes/myprobe/enable\n\tcat /sys/kernel/debug/tracing/trace\n\nHere\u0027s what happens to hit that BUG_ON():\n\n1) After installing kprobe at entry of sys_read, the first instruction\n   is replaced by \u0027ebreak\u0027 instruction on riscv64 platform.\n\n2) Once kernel reach the \u0027ebreak\u0027 instruction at the entry of sys_read,\n   it trap into the riscv breakpoint handler, where it do something to\n   setup for coming single-step of origin instruction, including backup\n   the \u0027sstatus\u0027 in pt_regs, followed by disable interrupt during single\n   stepping via clear \u0027SIE\u0027 bit of \u0027sstatus\u0027 in pt_regs.\n\n3) Then kernel restore to the instruction slot contains two instructions,\n   one is original instruction at entry of sys_read, the other is \u0027ebreak\u0027.\n   Here it trigger a \u0027Instruction page fault\u0027 exception (value at \u0027scause\u0027\n   is \u00270xc\u0027), if PF is not filled into PageTabe for that slot yet.\n\n4) Again kernel trap into page fault exception handler, where it choose\n   different policy according to the state of running kprobe. Because\n   afte 2) the state is KPROBE_HIT_SS, so kernel reset the current kp\n---truncated---"
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2024-05-29T04:59:31.486Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/fd0f06590d35c99f98d12c7984897ec4201a6263"
        },
        {
          "url": "https://git.kernel.org/stable/c/b1ebaa0e1318494a7637099a26add50509e37964"
        }
      ],
      "title": "riscv/kprobe: fix kernel panic when invoking sys_read traced by kprobe",
      "x_generator": {
        "engine": "bippy-a5840b7849dd"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2021-46957",
    "datePublished": "2024-02-27T18:46:58.701Z",
    "dateReserved": "2024-02-27T18:42:55.937Z",
    "dateUpdated": "2024-08-04T05:17:43.012Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.1",
  "meta": {
    "nvd": "{\"cve\":{\"id\":\"CVE-2021-46957\",\"sourceIdentifier\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"published\":\"2024-02-27T19:04:06.763\",\"lastModified\":\"2024-02-28T14:06:45.783\",\"vulnStatus\":\"Awaiting Analysis\",\"descriptions\":[{\"lang\":\"en\",\"value\":\"In the Linux kernel, the following vulnerability has been resolved:\\n\\nriscv/kprobe: fix kernel panic when invoking sys_read traced by kprobe\\n\\nThe execution of sys_read end up hitting a BUG_ON() in __find_get_block\\nafter installing kprobe at sys_read, the BUG message like the following:\\n\\n[   65.708663] ------------[ cut here ]------------\\n[   65.709987] kernel BUG at fs/buffer.c:1251!\\n[   65.711283] Kernel BUG [#1]\\n[   65.712032] Modules linked in:\\n[   65.712925] CPU: 0 PID: 51 Comm: sh Not tainted 5.12.0-rc4 #1\\n[   65.714407] Hardware name: riscv-virtio,qemu (DT)\\n[   65.715696] epc : __find_get_block+0x218/0x2c8\\n[   65.716835]  ra : __getblk_gfp+0x1c/0x4a\\n[   65.717831] epc : ffffffe00019f11e ra : ffffffe00019f56a sp : ffffffe002437930\\n[   65.719553]  gp : ffffffe000f06030 tp : ffffffe0015abc00 t0 : ffffffe00191e038\\n[   65.721290]  t1 : ffffffe00191e038 t2 : 000000000000000a s0 : ffffffe002437960\\n[   65.723051]  s1 : ffffffe00160ad00 a0 : ffffffe00160ad00 a1 : 000000000000012a\\n[   65.724772]  a2 : 0000000000000400 a3 : 0000000000000008 a4 : 0000000000000040\\n[   65.726545]  a5 : 0000000000000000 a6 : ffffffe00191e000 a7 : 0000000000000000\\n[   65.728308]  s2 : 000000000000012a s3 : 0000000000000400 s4 : 0000000000000008\\n[   65.730049]  s5 : 000000000000006c s6 : ffffffe00240f800 s7 : ffffffe000f080a8\\n[   65.731802]  s8 : 0000000000000001 s9 : 000000000000012a s10: 0000000000000008\\n[   65.733516]  s11: 0000000000000008 t3 : 00000000000003ff t4 : 000000000000000f\\n[   65.734434]  t5 : 00000000000003ff t6 : 0000000000040000\\n[   65.734613] status: 0000000000000100 badaddr: 0000000000000000 cause: 0000000000000003\\n[   65.734901] Call Trace:\\n[   65.735076] [\u003cffffffe00019f11e\u003e] __find_get_block+0x218/0x2c8\\n[   65.735417] [\u003cffffffe00020017a\u003e] __ext4_get_inode_loc+0xb2/0x2f6\\n[   65.735618] [\u003cffffffe000201b6c\u003e] ext4_get_inode_loc+0x3a/0x8a\\n[   65.735802] [\u003cffffffe000203380\u003e] ext4_reserve_inode_write+0x2e/0x8c\\n[   65.735999] [\u003cffffffe00020357a\u003e] __ext4_mark_inode_dirty+0x4c/0x18e\\n[   65.736208] [\u003cffffffe000206bb0\u003e] ext4_dirty_inode+0x46/0x66\\n[   65.736387] [\u003cffffffe000192914\u003e] __mark_inode_dirty+0x12c/0x3da\\n[   65.736576] [\u003cffffffe000180dd2\u003e] touch_atime+0x146/0x150\\n[   65.736748] [\u003cffffffe00010d762\u003e] filemap_read+0x234/0x246\\n[   65.736920] [\u003cffffffe00010d834\u003e] generic_file_read_iter+0xc0/0x114\\n[   65.737114] [\u003cffffffe0001f5d7a\u003e] ext4_file_read_iter+0x42/0xea\\n[   65.737310] [\u003cffffffe000163f2c\u003e] new_sync_read+0xe2/0x15a\\n[   65.737483] [\u003cffffffe000165814\u003e] vfs_read+0xca/0xf2\\n[   65.737641] [\u003cffffffe000165bae\u003e] ksys_read+0x5e/0xc8\\n[   65.737816] [\u003cffffffe000165c26\u003e] sys_read+0xe/0x16\\n[   65.737973] [\u003cffffffe000003972\u003e] ret_from_syscall+0x0/0x2\\n[   65.738858] ---[ end trace fe93f985456c935d ]---\\n\\nA simple reproducer looks like:\\n\\techo \u0027p:myprobe sys_read fd=%a0 buf=%a1 count=%a2\u0027 \u003e /sys/kernel/debug/tracing/kprobe_events\\n\\techo 1 \u003e /sys/kernel/debug/tracing/events/kprobes/myprobe/enable\\n\\tcat /sys/kernel/debug/tracing/trace\\n\\nHere\u0027s what happens to hit that BUG_ON():\\n\\n1) After installing kprobe at entry of sys_read, the first instruction\\n   is replaced by \u0027ebreak\u0027 instruction on riscv64 platform.\\n\\n2) Once kernel reach the \u0027ebreak\u0027 instruction at the entry of sys_read,\\n   it trap into the riscv breakpoint handler, where it do something to\\n   setup for coming single-step of origin instruction, including backup\\n   the \u0027sstatus\u0027 in pt_regs, followed by disable interrupt during single\\n   stepping via clear \u0027SIE\u0027 bit of \u0027sstatus\u0027 in pt_regs.\\n\\n3) Then kernel restore to the instruction slot contains two instructions,\\n   one is original instruction at entry of sys_read, the other is \u0027ebreak\u0027.\\n   Here it trigger a \u0027Instruction page fault\u0027 exception (value at \u0027scause\u0027\\n   is \u00270xc\u0027), if PF is not filled into PageTabe for that slot yet.\\n\\n4) Again kernel trap into page fault exception handler, where it choose\\n   different policy according to the state of running kprobe. Because\\n   afte 2) the state is KPROBE_HIT_SS, so kernel reset the current kp\\n---truncated---\"},{\"lang\":\"es\",\"value\":\"En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: riscv/kprobe: corrige el p\u00e1nico del kernel al invocar sys_read rastreado por kprobe La ejecuci\u00f3n de sys_read termina con un BUG_ON() en __find_get_block despu\u00e9s de instalar kprobe en sys_read, el mensaje de ERROR es como el siguiente : [65.708663] ------------[ cortar aqu\u00ed ]------------ [ 65.709987] \u00a1ERROR del kernel en fs/buffer.c:1251! [65.711283] ERROR del kernel [#1] [65.712032] M\u00f3dulos vinculados en: [65.712925] CPU: 0 PID: 51 Comm: sh No contaminado 5.12.0-rc4 #1 [65.714407] Nombre de hardware: riscv-virtio,qemu (DT ) [ 65.715696] epc : __find_get_block+0x218/0x2c8 [ 65.716835] ra : __getblk_gfp+0x1c/0x4a [ 65.717831] epc : ffffffe00019f11e ra : ffffffe00019f56a sp : ffffffe00243 7930 [65.719553] gp: ffffffe000f06030 tp: ffffffe0015abc00 t0: ffffffe00191e038 [65.721290] t1: ffffffe00191e038 t2: 000000000000000a s0: ffffffe002437960 [65.723051] s1: ffffffe00160ad00 a0: ffffffe00160ad00 a1: 000000000000012a [65.724772 ] a2 : 0000000000000400 a3 : 0000000000000008 a4 : 0000000000000040 [ 65.726545] a5 : 00000000000000000 a6 : ffffffe00191e000 a7 : 0000000000000 0000 [65.728308] s2: 000000000000012a s3 : 0000000000000400 s4 : 0000000000000008 [ 65.730049] s5 : 000000000000006c s6 : ffffffe00240f800 s7 : ffffffe000f080a8 [ 65.731802] s8 : 0 000000000000001 s9: 000000000000012a s10: 0000000000000008 [65.733516] s11: 00000000000000008 t3: 00000000000003ff t4: 0000000000 00000f [65.734434] t5: 00000000000003ff t6: 0000000000040000 [65.734613] estado: 0000000000000100 badaddr: 00000000000000000 causa: 0000000000000003 [65.734901] Seguimiento de llamadas: [65.735076] [] __find_get_block+ 0x218/0x2c8 [ 65.735417] [] __ext4_get_inode_loc+0xb2/0x2f6 [ 65.735618] [] ext4_get_inode_loc+0x3a/0x8a [ 65.735802] [] ext4_reserve_inode_write+0x2e/0x8c [ 65.735999] [] __ext4_mark_inode_dirty+0x4c/0x18e [ 65.736208] [] ext4_dirty_inode+0x46/0x66 [ 65.736387] [ ] __mark_inode_dirty+0x12c/0x3da [ 65.736576] [] touch_atime+0x146/0x150 [ 65.736748] [] filemap_read+0x234/0x246 [ 65.736920] [] generic_file_read_iter+0xc0/0x114 [ 65.737114 ] [] ext4_file_read_iter+0x42/0xea [ 65.737310] [] new_sync_read+0xe2/0x15a [ 65.737483] [] vfs_read+0xca/0xf2 [ 65.737641] [] ksys_read+0x5e/0xc8 [ 65.737816] [] sys_read+0xe/0x16 [ 65.737973] [] ret_from_syscall+0x0/0x2 [ 65.738858] ---[ end trace fe93f985456c935d ]--- A El reproductor simple se ve as\u00ed: echo \u0027p: myprobe sys_read fd=%a0 buf=%a1 count=%a2\u0027 \u0026gt; /sys/kernel/debug/tracing/kprobe_events echo 1 \u0026gt; /sys/kernel/debug/tracing/events/kprobes/myprobe/enable cat /sys/kernel /debug/tracing/trace Esto es lo que sucede cuando se activa ese BUG_ON(): 1) Despu\u00e9s de instalar kprobe en la entrada de sys_read, la primera instrucci\u00f3n se reemplaza por la instrucci\u00f3n \u0027ebreak\u0027 en la plataforma riscv64. 2) Una vez que el kernel alcanza la instrucci\u00f3n \u0027ebreak\u0027 en la entrada de sys_read, entra en el controlador de punto de interrupci\u00f3n riscv, donde hace algo para configurar la siguiente instrucci\u00f3n de origen de un solo paso, incluida una copia de seguridad del \u0027sstatus\u0027 en pt_regs, seguido de deshabilite la interrupci\u00f3n durante un solo paso mediante el bit \u0027SIE\u0027 claro de \u0027sstatus\u0027 en pt_regs. 3) Luego, la restauraci\u00f3n del kernel en la ranura de instrucciones contiene dos instrucciones, una es la instrucci\u00f3n original en la entrada de sys_read y la otra es \u0027ebreak\u0027. Aqu\u00ed se activa una excepci\u00f3n de \u0027Error en la p\u00e1gina de instrucciones\u0027 (el valor en \u0027scause\u0027 es \u00270xc\u0027), si el PF a\u00fan no se ha completado en PageTabe para ese espacio.---truncado---\"}],\"metrics\":{},\"references\":[{\"url\":\"https://git.kernel.org/stable/c/b1ebaa0e1318494a7637099a26add50509e37964\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/fd0f06590d35c99f98d12c7984897ec4201a6263\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"}]}}"
  }
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading...

Loading...