Instituto Nacional de ciberseguridad. Sección Incibe
Instituto Nacional de Ciberseguridad. Sección INCIBE-CERT

Vulnerabilidad en kernel de Linux (CVE-2023-53143)

Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
02/05/2025
Última modificación:
05/05/2025

Descripción

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: ext4: corrige otro error de fsmap de un bloque en sistemas de archivos de 1k Aparentemente, syzbot descubrió que emitir esta llamada FSMAP: Produce este fallo si el sistema de archivos subyacente es un sistema de archivos ext4 de 1k bloques: ¡ERROR del kernel en fs/ext4/ext4.h:3331! Código de operación no válido: 0000 [#1] PREEMPT SMP CPU: 3 PID: 3227965 Comm: xfs_io Contaminado: GWO 6.2.0-rc8-achx Nombre del hardware: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 01/04/2014 RIP: 0010:ext4_mb_load_buddy_gfp+0x47c/0x570 [ext4] RSP: 0018:ffffc90007c03998 EFLAGS: 00010246 RAX: ffff888004978000 RBX: ffffc90007c03a20 RCX: ffff888041618000 RDX: 0000000000000000 RSI: 00000000000005a4 RDI: ffffffffa0c99b11 RBP: ffff888012330000 R08: ffffffffa0c2b7d0 R09: 0000000000000400 R10: ffffc90007c03950 R11: 0000000000000000 R12: 000000000000001 R13: 00000000ffffffff R14: 0000000000000c40 R15: ffff88802678c398 FS: 00007fdf2020c880(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffd318a5fe8 CR3: 000000007f80f001 CR4: 00000000001706e0 Rastreo de llamadas: ext4_mballoc_query_range+0x4b/0x210 [ext4 dfa189daddffe8fecd3cdfd00564e0f265a8ab80] ext4_getfsmap_datadev+0x713/0x890 [ext4 dfa189daddffe8fecd3cdfd00564e0f265a8ab80] ext4_getfsmap+0x2b7/0x330 [ext4 dfa189daddffe8fecd3cdfd00564e0f265a8ab80] ext4_ioc_getfsmap+0x153/0x2b0 [ext4 dfa189daddffe8fecd3cdfd00564e0f265a8ab80] __ext4_ioctl+0x2a7/0x17e0 [ext4 dfa189daddffe8fecd3cdfd00564e0f265a8ab80] __x64_sys_ioctl+0x82/0xa0 hacer_llamada_al_sistema_64+0x2b/0x80 entrada_LLAMADA_AL_SISTEMA_64_después_de_hwframe+0x46/0xb0 RIP: 0033:0x7fdf20558aff RSP: 002b:00007ffd318a9e30 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00000000000200c0 RCX: 00007fdf20558aff RDX: 00007fdf1feb2010 RSI: 00000000c0c0583b RDI: 0000000000000003 RBP: 00005625c0634be0 R08: 00005625c0634c40 R09: 0000000000000001 R10: 0000000000000000 R11: 0000000000000246 R12: 00007fdf1feb2010 R13: 00005625be70d994 R14: 000000000000800 R15: 000000000000000 Para las llamadas GETFSMAP, el llamador selecciona un dispositivo de bloque físico escribiendo su número de bloque en fsmap_head.fmh_keys[01].fmr_device. Para consultar las asignaciones de un subrango del dispositivo, el byte inicial del rango se escribe en fsmap_head.fmh_keys[0].fmr_physical y el último byte en fsmap_head.fmh_keys[1].fmr_physical. IOWs, para consultar qué asignaciones se superponen con los bytes 3-14 de /dev/sda, debe configurar las entradas de la siguiente manera: fmh_keys[0] = { .fmr_device = major(8, 0), .fmr_physical = 3}, fmh_keys[1] = { .fmr_device = major(8, 0), .fmr_physical = 14}, lo que le devolvería lo que esté asignado en los 12 bytes a partir del desplazamiento físico 3. El fallo se debe a una validación de rango insuficiente de keys[1] en ext4_getfsmap_datadev. En sistemas de archivos de 1k bloques, el bloque 0 no forma parte del sistema de archivos, lo que significa que s_first_data_block es distinto de cero. ext4_get_group_no_and_offset resta esta cantidad del argumento blocknr antes de descomponerlo en un número de grupo y un número de bloque dentro de un grupo. En las IOW, el grupo de bloques 0 abarca los bloques 1-8192 (basado en 1) en lugar de 0-8191 (basado en 0), como ocurre con tamaños de bloque mayores. El resultado final de esta codificación es que blocknr < s_first_data_block no es una entrada válida para esta función. La variable end_fsb se establece a partir de las claves copiadas del espacio de usuario, lo que significa que, en el ejemplo anterior, su valor es cero. Esto genera un desbordamiento por debajo de la capacidad: blocknr = blocknr - le32_to_cpu(es->s_first_data_block); La división opera entonces sobre -1: offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb)) >> EXT4_SB(sb)->s_cluster_bits; De esta manera, se deja un número de grupo imposiblemente grande (2^32-1) en blocknr. ext4_getfsmap_check_keys verificó que keys[0 ---truncado---

Impacto