TECH 으로 돌아가기
TECH HACKER NEWS 어제 6분 읽기 29 READS

안드로이드 17 bionic 와이드 문자열 버그, 그리고 닫힌 AOSP 소스

안드로이드 17 bionic 와이드 문자열 버그, 그리고 닫힌 AOSP 소스
SOURCE IMAGE · HACKER NEWS

안드로이드의 C 표준 라이브러리인 bionic에서 와이드 문자열 함수 두 개가 조용히 오작동하고 있다는 보고가 NDK 이슈 트래커에 올라왔다. 2026년 9월자 안드로이드 17 빌드에서 wcscspn()과 wcspbrk()가, 제외 집합(reject set)에 들어 있는 문자가 두 개 이상이고 그 문자들이 모두 U+0100 미만일 때, 문자열에서 U+0100 이상인 첫 문자를 만나면 그 자리에서 스캔을 멈춰 버린다는 것이다. 집합에 포함되지도 않은 그 문자를 '일치'로 보고하는 셈이다. 같은 계열이라도 wcsspn(), wcschr(), wcsrchr(), wmemchr(), wcsstr()은 정상 동작한다.

얼핏 사소해 보이지만 영향 범위는 넓다. 개행 문자나 와일드카드 같은 ASCII 구분자를 찾기 위해 와이드 문자열을 훑는 코드는, 텍스트에 이모지나 한중일 문자, 키릴·그리스 문자, 라틴 확장 문자가 하나라도 섞이는 순간 깨진다. 한국어 환경이라면 한글이 모두 U+0100을 한참 넘어서는 영역에 있으므로, 한글이 포함된 입력을 와이드 문자로 처리하는 경로가 있다면 사실상 상시 노출되는 문제다.

재현과 원인

보고자는 NDK(aarch64-linux-android30-clang)로 빌드한 바이너리를 /data/local/tmp에 올리고 adb shell로 실행해 이를 측정했다. U+0001부터 U+10FFFF까지(서로게이트와 집합 구성원 두 개 제외) 전 코드포인트를 wcscspn(L"\n", L"x\n") 형태로 쓸어본 결과, U+0100부터 U+10FFFF까지 정확히 1,111,808개 코드포인트에서 1이 아닌 0이 반환됐다. U+0001~U+00FF 구간은 모두 정상이었다. 측정은 Pixel 8a에서 이뤄졌다.

CP3A.260905.009 빌드의 /apex/com.android.runtime/lib64/bionic/libc.so를 디스어셈블한 결과, wcscspn은 집합 모양에 따라 세 갈래 경로로 분기한다. 모든 구성원이 0x100 미만인 집합에는 0x100 이상인 문자가 결코 들어갈 수 없으므로, wcscspn이라면 그 문자를 지나쳐 계속 스캔해야 맞다. 그런데 구현은 거기서 멈춘다. 구조가 동일한 wcsspn은 '유지 집합'에 없는 문자를 만나면 멈추는 것이 올바른 동작이라, 여집합 성격의 wcscspn·wcspbrk만 틀어진 것이다. wcspbrk는 이 스캔 위에 얹혀 있어 같은 버그를 물려받는다.

주목할 지점은 이것이 언제 들어왔느냐다. 공개된 android17-release 소스(android-17.0.0_r1, 2026년 6월)는 external/llvm-libc 기반의 단순 중첩 루프로 이들 함수를 만들며 정상이다. 9월 빌드의 코드는 이와 다르다. 즉 회귀는 6월과 9월 릴리스 사이에 유입됐는데, 실제 Pixel에서 한 달 넘게 안정 운영 중인 안드로이드 17 QPR1의 소스는 아직 공개되지 않아 외부에서 확인할 길이 없다.

테스트 공백과 실제 피해

이 버그가 걸러지지 않은 이유는 테스트에 있다. tests/wchar_test.cpp의 기존 TEST(wchar, wcspbrk)는 ASCII 입력만 쓴다. EXPECT_EQ(3u, wcscspn(L"aĀb\n", L"x\n"))처럼 비ASCII 문자를 끼운 단언 하나면 잡혔을 문제다. 유지보수 측은 ToT(최신 트리)에서도 여전히 재현됨을 확인했고, 누락된 테스트 두 개를 추가하고 비ASCII 입력을 쓰지 않는 다른 테스트들도 점검하며, 영향 기기를 줄이기 위한 백포트를 시도하겠다고 밝혔다. 기존 wcscspn 테스트 자체가 잘못 작성돼 있었다는 점도 함께 인정됐다.

실제 피해 사례로는 안드로이드용 Visual Pinball이 거론됐다. Wine의 vbscript 엔진을 유닉스 빌드한 libwinevbs의 렉서가 주석을 건너뛰려고 wcspbrk(ptr, L"\n\r")를 호출하는데, 9월 업데이트 이후 주석에 이모지가 들어간 VBScript 소스를 담은 테이블이 전혀 로드되지 않았다. 함수가 줄 끝이 아니라 첫 이모지 위치를 돌려주면서 "Invalid character" 오류를 냈기 때문이다. FileSystem.MoveFolder 역시 wcspbrk(src, L"*?>

SOURCE · HACKER NEWS
원문 전체 보기 → https://github.com/android/ndk/issues/2260
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기 →
처리 중...