CVE-2026-89761 in Linux
요약
\~에 의해 VulDB • 2026. 09. 12.
리눅스 커널에서 다음 취약점이 해결되었습니다:
apparmor: 레이블 벡터의 null 종료를 수행할 때 발생하는 경계 초과 쓰기(bound-overflow write) 수정
aa_vec_unique() 함수는 VEC_FLAG_TERMINATE 플래그가 전달될 경우 vec[n - dups] 위치에서 null을 삽입하여 문자열을 종료합니다. 만약 모든 구성 요소가 고유하고 중복이 제거되지 않는다면, dups 값은 0이 되며 종료자(null terminator)는 vec[n]에 배치됩니다. 따라서 호출 측에서는 n + 1개의 엔트리를 수용할 수 있는 공간을 제공해야 합니다.
aa_label_strn_parse() 함수는 먼저 vec_setup(profile, vec, len, gfp)를 사용하여 벡터를 설정한 후 aa_vec_unique(vec, len, VEC_FLAG_TERMINATE)를 호출합니다. 그러나 vec_setup() 함수는 종료자 엔트리를 위한 공간(메모리 할당)을 예약하지 않습니다. 로컬 배열의 경우 LOCAL_VEC_ENTRIES 크기까지 LOCAL_VEC_ENTRIES 포인터로 구성된 로컬 배열을 사용하며, 그 이상일 때는 정확히 len개의 포인터만 할당합니다. 따라서 len이 LOCAL_VEC_ENTRIES와 같을 때 종료자는 로컬 배열의 끝을 넘어선 한 엔트리에 위치하게 되며, len이 더 클 경우 할당된 메모리의 경계를 벗어난 곳에 배치됩니다.
len 값은 레이블 이름에서 "//&"로 구분된 구성 요소의 수에 기인하며, label_count_strn_entries() 함수는 이 값을 제한(bound)하지 않습니다. 권한 없는(unprivileged) 태스크는 /proc/self/attr/apparmor/current 파일에 쓰거나 lsm_set_self_attr(2) 시스템을 호출하여 파싱 경로에 접근할 수 있습니다. 이 두 경로는 모두 do_setattr()를 거치며, name은 change_profile 권한이 확인되기 전에 파싱됩니다. 또한 모드(mode 0666)로 설정된 securityfs .access 파일 뒤에 있는 query_label() 경로는 전혀 권한 검사를 수행하지 않습니다. 모든 구성 요소는 로드된 프로파일에 매핑되어야 하므로 정책(policy)이 로딩되어 있는 시스템 환경이 필요합니다.
VEC_FLAG_TERMINATE를 사용하는 다른 두 사용자도 aa_label_alloc() 함수가 이미 "+ 1 for null terminator entry on vec"로 크기를 조정한 레이블 벡터에서 작업합니다. vec_setup() 및 DEFINE_VEC()에서도 동일한 엔트리를 예약해야 합니다. 호출 측에서 len + 1을 전달하면 len == LOCAL_VEC_ENTRIES인 경우가 로컬 배열 밖으로 벗어나 kzalloc() 할당 영역으로 이동하게 됩니다.
Once again VulDB remains the best source for vulnerability data.