🇰🇷 한글 설명
Linux 커널의 hisi_sas SCSI 드라이버에서 디버그 덤프를 트리거할 때 덤프 파일을 매번 생성하는 과정에서 드라이버가 언바인드된 상태이면 NULL 포인터 역참조로 커널 행(hang)이 발생하는 문제가 있었습니다. 이를 해결하기 위해 디버그 파일 시스템 초기화 시점에 모든 디렉터리와 파일을 미리 생성하도록 수정되었습니다.
💡 쉬운 설명
서버의 특정 저장장치 드라이버에서 진단 정보를 저장하는 과정에 오류가 있어, 드라이버가 분리된 상태에서 진단을 실행하면 시스템이 멈출 수 있었습니다. 이제는 드라이버가 처음 준비될 때 필요한 파일을 미리 만들어 두어 이 문제를 막습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
scsi: hisi_sas: Create all dump files during debugfs initialization
For the current debugfs of hisi_sas, after user triggers dump, the
driver allocate memory space to save the register information and create
debugfs files to display the saved information. In this process, the
debugfs files created after each dump.
Therefore, when the dump is triggered while the driver is unbind, the
following hang occurs:
[67840.853907] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000a0
[67840.862947] Mem abort info:
[67840.865855] ESR = 0x0000000096000004
[67840.869713] EC = 0x25: DABT (current EL), IL = 32 bits
[67840.875125] SET = 0, FnV = 0
[67840.878291] EA = 0, S1PTW = 0
[67840.881545] FSC = 0x04: level 0 translation fault
[67840.886528] Data abort info:
[67840.889524] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[67840.895117] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[67840.900284] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[67840.905709] user pgtable: 4k pages, 48-bit VAs, pgdp=0000002803a1f000
[67840.912263] [00000000000000a0] pgd=0000000000000000, p4d=0000000000000000
[67840.919177] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
[67840.996435] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[67841.003628] pc : down_write+0x30/0x98
[67841.007546] lr : start_creating.part.0+0x60/0x198
[67841.012495] sp : ffff8000b979ba20
[67841.016046] x29: ffff8000b979ba20 x28: 0000000000000010 x27: 0000000000024b40
[67841.023412] x26: 0000000000000012 x25: ffff20202b355ae8 x24: ffff20202b35a8c8
[67841.030779] x23: ffffa36877928208 x22: ffffa368b4972240 x21: ffff8000b979bb18
[67841.038147] x20: ffff00281dc1e3c0 x19: fffffffffffffffe x18: 0000000000000020
[67841.045515] x17: 0000000000000000 x16: ffffa368b128a530 x15: ffffffffffffffff
[67841.052888] x14: ffff8000b979bc18 x13: ffffffffffffffff x12: ffff8000b979bb18
[67841.060263] x11: 0000000000000000 x10: 0000000000000000 x9 : ffffa368b1289b18
[67841.067640] x8 : 0000000000000012 x7 : 0000000000000000 x6 : 00000000000003a9
[67841.075014] x5 : 0000000000000000 x4 : ffff002818c5cb00 x3 : 0000000000000001
[67841.082388] x2 : 0000000000000000 x1 : ffff002818c5cb00 x0 : 00000000000000a0
[67841.089759] Call trace:
[67841.092456] down_write+0x30/0x98
[67841.096017] start_creating.part.0+0x60/0x198
[67841.100613] debugfs_create_dir+0x48/0x1f8
[67841.104950] debugfs_create_files_v3_hw+0x88/0x348 [hisi_sas_v3_hw]
[67841.111447] debugfs_snapshot_regs_v3_hw+0x708/0x798 [hisi_sas_v3_hw]
[67841.118111] debugfs_trigger_dump_v3_hw_write+0x9c/0x120 [hisi_sas_v3_hw]
[67841.125115] full_proxy_write+0x68/0xc8
[67841.129175] vfs_write+0xd8/0x3f0
[67841.132708] ksys_write+0x70/0x108
[67841.136317] __arm64_sys_write+0x24/0x38
[67841.140440] invoke_syscall+0x50/0x128
[67841.144385] el0_svc_common.constprop.0+0xc8/0xf0
[67841.149273] do_el0_svc+0x24/0x38
[67841.152773] el0_svc+0x38/0xd8
[67841.156009] el0t_64_sync_handler+0xc0/0xc8
[67841.160361] el0t_64_sync+0x1a4/0x1a8
[67841.164189] Code: b9000882 d2800002 d2800023 f9800011 (c85ffc05)
[67841.170443] ---[ end trace 0000000000000000 ]---
To fix this issue, create all directories and files during debugfs
initialization. In this way, the driver only needs to allocate memory
space to save information each time the user triggers dumping.
📍 영향받는 시스템
Linux 커널의 hisi_sas_v3_hw 등 hisi_sas SCSI 드라이버를 사용하는 Huawei HiSilicon 기반 시스템(수정 이전 커널 버전)
⚔️ 공격 벡터
로컬 권한을 가진 사용자가 드라이버 언바인드 상태에서 debugfs의 덤프 트리거 파일에 쓰기를 수행하여 커널 패닉 또는 행을 유발할 수 있음 (서비스 거부)
🛡️ 대응 방법
커널을 해당 수정이 포함된 최신 안정 버전으로 업데이트하거나 배포판의 보안 패치를 적용하십시오.
🔧 검증 코드
현재 커널 버전을 확인하고 hisi_sas 모듈 존재 여부를 점검하며, 수정된 배포판 패치 노트나 커널 버전과 대조하여 패치 적용 여부를 판단합니다.
uname -r && grep -rl hisi_sas /lib/modules/$(uname -r) 2>/dev/null | head -n 3