🇰🇷 한글 설명
Linux 커널의 md(Multiple Device) 드라이버 내 super_1_load() 함수에서 발생하는 취약점입니다. 디스크의 슈퍼블록에서 읽어온 bblog_shift 값이 적절히 검증되지 않아, 비정상적인 값으로 인해 sector 및 count 계산 시 정수 오버플로가 발생할 수 있습니다.
💡 쉬운 설명
컴퓨터가 디스크 정보를 읽을 때 잘못된 숫자를 사용하여 계산 오류를 일으키는 문제입니다. 이 오류를 이용하면 시스템의 데이터 관리 영역에 문제가 생길 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
md: do overflow check for sb->bblog_shift in super_1_load()
In super_1_load(), sb->bblog_shift is an __u8 type value loaded from on-
disk superblock. It is used for badblocks API badblocks_set() by the
following sequence,
1930 rdev->badblocks.shift = sb->bblog_shift;
1931 for (i = 0 ; i < (sectors << (9-3)) ; i++, bbp++) {
1932 u64 bb = le64_to_cpu(*bbp);
1933 int count = bb & (0x3ff);
1934 u64 sector = bb >> 10;
1935 sector <<= sb->bblog_shift;
1936 count <<= sb->bblog_shift;
1937 if (bb + 1 == 0)
1938 break;
1939 if (!badblocks_set(&rdev->badblocks, sector, count, 1))
1940 return -EINVAL;
1941 }
bb->bblog_shit is in range of 0-255, variable sector is 64bit width, for
an invalid bb->bblog_shit, it is possible to make sector be overflowed
by the following calculation,
1935 sector <<= sb->bblog_shift;
Then in turn when call badblocks_set() at line 1939 with the invalid
rdev->badblocks.shift set at line 1930, may result an overflow inside
_badblocks_clear() in block/badblocks.c.
Although there are many places to call badblocks APIs, the non-zero
shift value is only used in super_1_load(), other places always use 0 as
the shift value. Therefore it is unnecessary to do a general shift value
overflow check inside badblock API, and just check here as the caller.
This may avoid unnecessary check, make the badblocks API code more simple
and elegant.
📍 영향받는 시스템
Linux kernel (md driver 사용 시스템)
⚔️ 공격 벡터
조작된 슈퍼블록(superblock) 데이터를 포함한 디스크를 시스템에 마운트하여 발생
🛡️ 대응 방법
Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 super_1_load() 내 오버플로 검증 로직을 적용해야 함
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 해결된 패치 버전 이후인지 확인