🇰🇷 한글 설명
Linux 커널의 AppArmor 구성 요소에서 레이블 벡터의 널 종료(null termination) 처리 시 경계 외 쓰기(out-of-bounds write) 취약점이 발견되었습니다. 레이블 이름을 파싱할 때 필요한 공간을 충분히 확보하지 않아, 특정 조건에서 메모리 범위를 벗어난 쓰기가 발생할 수 있습니다. 이는 권한이 없는 사용자가 `/proc/self/attr/apparmor/current` 등을 통해 악용할 수 있습니다.
💡 쉬운 설명
컴퓨터가 이름을 저장할 때 마지막에 '끝'을 알리는 표시를 남겨야 하는데, 저장 공간을 계산할 때 이 표시를 위한 자리를 미리 만들어두지 않아 옆 칸을 침범하는 문제입니다. 이를 통해 해커가 시스템의 메모리를 조작하여 보안을 무력화할 위험이 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
apparmor: fix out-of-bounds write when null terminating a label vec
aa_vec_unique() null terminates at vec[n - dups] when VEC_FLAG_TERMINATE
is passed. If the components are all distinct no duplicates are dropped,
dups is 0 and the terminator goes to vec[n], so the caller has to provide
room for n + 1 entries.
aa_label_strn_parse() sets up its vector with vec_setup(profile, vec, len,
gfp) and then calls aa_vec_unique(vec, len, VEC_FLAG_TERMINATE), but
vec_setup() does not reserve the terminator entry. Up to LOCAL_VEC_ENTRIES
it uses the local array of LOCAL_VEC_ENTRIES pointers, above that it
allocates exactly len pointers. The terminator therefore lands one entry
past the end of the local array when len is LOCAL_VEC_ENTRIES, and one
entry past the end of the allocation when len is larger.
len comes from the number of "//&" separated components in the label name
and label_count_strn_entries() does not bound it. An unprivileged task
reaches the parse by writing to /proc/self/attr/apparmor/current or through
lsm_set_self_attr(2), both of which go through do_setattr(), and the name
is parsed before the change_profile permission is checked.
The query_label() path behind the securityfs .access file, which is
mode 0666, performs no permission check at all. Every component has to
resolve to a loaded profile, so a system with policy loaded is required.
The other two VEC_FLAG_TERMINATE users work on a label vec that
aa_label_alloc() has already sized with "+ 1 for null terminator entry on
vec". Reserve the same entry in vec_setup() and DEFINE_VEC(). Passing
len + 1 from the caller instead would move len == LOCAL_VEC_ENTRIES out of
the local array and into kzalloc().
📍 영향받는 시스템
AppArmor가 활성화된 Linux 커널 (특정 패치 전 버전)
⚔️ 공격 벡터
권한이 없는 사용자가 특수하게 조작된 AppArmor 레이블 이름을 시스템 파일이나 시스템 호출을 통해 입력하여 메모리 오염 유도
🛡️ 대응 방법
AppArmor 레이블 파싱 시 널 종료를 위한 추가 공간을 확보하도록 커널을 최신 버전으로 업데이트
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 보안 패치 버전 이후인지 확인