🇰🇷 한글 설명
Linux 커널의 pstore/ram 구성 요소에서 persistent_ram_save_old() 함수 호출 시 버퍼 오버플로우가 발생할 수 있는 취약점입니다. 버퍼 크기가 이전 할당 시점보다 커질 경우, 잘못된 크기 정보로 인해 힙 메모리 영역에 범위를 벗어난 쓰기(OOB write) 및 읽기(OOB read)가 발생합니다.
💡 쉬운 설명
시스템이 비정상 종료된 기록을 저장하는 과정에서, 저장 공간의 크기를 잘못 계산하여 메모리의 허용된 범위를 넘어 데이터를 쓰는 오류입니다. 이로 인해 시스템이 충돌하거나 보안 문제가 생길 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
pstore/ram: fix buffer overflow in persistent_ram_save_old()
persistent_ram_save_old() can be called multiple times for the same
persistent_ram_zone (e.g., via ramoops_pstore_read -> ramoops_get_next_prz
for PSTORE_TYPE_DMESG records).
Currently, the function only allocates prz->old_log when it is NULL,
but it unconditionally updates prz->old_log_size to the current buffer
size and then performs memcpy_fromio() using this new size. If the
buffer size has grown since the first allocation (which can happen
across different kernel boot cycles), this leads to:
1. A heap buffer overflow (OOB write) in the memcpy_fromio() calls
2. A subsequent OOB read when ramoops_pstore_read() accesses the buffer
using the incorrect (larger) old_log_size
The KASAN splat would look similar to:
BUG: KASAN: slab-out-of-bounds in ramoops_pstore_read+0x...
Read of size N at addr ... by task ...
The conditions are likely extremely hard to hit:
0. Crash with a ramoops write of less-than-record-max-size bytes.
1. Reboot: ramoops registers, pstore_get_records(0) reads old crash,
allocates old_log with size X
2. Crash handler registered, timer started (if pstore_update_ms >= 0)
3. Oops happens (non-fatal, system continues)
4. pstore_dump() writes oops via ramoops_pstore_write() size Y (>X)
5. pstore_new_entry = 1, pstore_timer_kick() called
6. System continues running (not a panic oops)
7. Timer fires after pstore_update_ms milliseconds
8. pstore_timefunc() → schedule_work() → pstore_dowork() → pstore_get_records(1)
9. ramoops_get_next_prz() → persistent_ram_save_old()
10. buffer_size() returns Y, but old_log is X bytes
11. Y > X: memcpy_fromio() overflows heap
Requirements:
- a prior crash record exists that did not fill the record size
(almost impossible since the crash handler writes as much as it
can possibly fit into the record, capped by max record size and
the kmsg buffer almost always exceeds the max record size)
- pstore_update_ms >= 0 (disabled by default)
- Non-fatal oops (system survives)
Free and reallocate the buffer when the new size differs from the
previously allocated size. This ensures old_log always has sufficient
space for the data being copied.
📍 영향받는 시스템
Linux Kernel (pstore/ram 모듈 사용 환경)
⚔️ 공격 벡터
특정 조건(비치명적 Oops 발생 및 pstore_update_ms 설정 등)이 충족된 상태에서 시스템 재부팅 및 로그 기록 과정 중 발생
🛡️ 대응 방법
커널 패치를 통해 버퍼 크기가 변경될 경우 기존 버퍼를 해제하고 새로운 크기에 맞게 재할당하도록 업데이트해야 합니다.
🔧 검증 코드
현재 실행 중인 커널 버전을 확인하여 해당 취약점이 해결된 최신 보안 패치 버전인지 확인합니다.