# HWAddressSanitizer

## HWAddressSanitizer 란?

{% hint style="info" %}
**참고:** 이 페이지에서는 Android 플랫폼 구성요소에서 [HWAddressSanitizer](https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html)를 사용하는 방법을 다룹니다. HWAddressSanitizer에서 NDK로 빌드된 Android 앱을 실행하는 방법에 관한 자세한 내용은 [개발자 문서](https://developer.android.com/ndk/guides/hwasan?hl=ko)를 참고하세요.
{% endhint %}

*HWASan 비정상 종료를 읽는 방법에 관한 자세한 내용은* [*HWASan 보고서 이해하기*](https://source.android.com/docs/security/test/memory-safety/hwasan-reports?hl=ko)*를 참고하세요.*

하드웨어 지원 AddressSanitizer(HWASan)는 [AddressSanitizer](https://source.android.com/docs/security/test/asan?hl=ko)와 유사한 메모리 오류 감지 도구입니다. HWASan은 ASan에 비해 RAM을 훨씬 적게 사용하므로 전체 시스템 정리에 적합합니다. HWASan은 Android 10 이상 및 AArch64 하드웨어에서만 사용할 수 있습니다.

주로 C/C++ 코드에 유용하지만 HWASan은 자바 인터페이스를 구현하는 데 사용되는 C/C++에서 비정상 종료를 일으키는 자바 코드를 디버그하는 데도 도움이 될 수 있습니다. 메모리 오류가 발생할 때 이를 포착하여 원인이 된 코드를 직접 가리키므로 유용합니다.

미리 빌드된 HWASan 이미지를 [ci.android.com](https://ci.android.com/builds/branches/aosp-master-with-phones-throttled/grid?hl=ko)에서 지원되는 Pixel 기기에 플래시할 수 있습니다([자세한 설정 안내](https://developer.android.com/ndk/guides/hwasan?hl=ko)).

HWASan은 기본 ASan과 비교하여 다음과 같은 이점이 있습니다.

* 유사한 CPU 오버헤드(최대 2배)
* 유사한 코드 크기 오버헤드(40\~50%)
* RAM 오버헤드가 훨씬 적음(10%\~35%)

HWASan은 다음과 같이 ASan과 동일한 버그 집합을 감지합니다.

* 스택 및 힙 버퍼 오버플로우/언더플로우
* 프리 후 힙 사용
* 범위를 벗어난 스택 사용
* 더블 프리/와일드 프리

또한 HWASan은 반환 후에 스택 사용을 감지합니다.

HWASan은 ASan과 마찬가지로 [UBSan](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html)과 호환됩니다. 타겟에서 동시에 이 둘을 사용 설정할 수 있습니다.

## 구현 세부정보 및 제한사항 <a href="#implementation" id="implementation"></a>

HWASan은 [메모리 태그하기](https://arxiv.org/pdf/1802.09517) 접근 방식을 기반으로 하며, 작은 임의 태그 값이 포인터 및 메모리 주소 범위와 연결됩니다. 메모리 액세스가 유효하려면 포인터와 메모리 태그가 일치해야 합니다. HWASan은 포인터 태그를 주소의 최상위 비트에 저장하기 위해 *가상 주소 태그하기*라고도 하는 ARMv8의 기능인 TBI(Top Byte Ignore)를 사용합니다.

[HWASan의 설계](http://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html)에 관한 자세한 내용은 Clang 문서 사이트를 참조하세요.

의도적으로, HWASan에는 오버플로우 감지를 위한 ASan의 크기가 제한된 Redzone 또는 해제 후 사용 감지를 위한 ASan의 제한된 용량 격리 저장소가 없습니다. 따라서 HWASan은 오버플로우의 크기 또는 메모리 할당 취소 기간에 상관없이 버그를 감지할 수 있습니다. 덕분에 HWASan은 ASan에 비해 큰 이점을 갖습니다.

하지만 HWASan은 가능한 태그 값이 256개로 제한되어 있으므로 프로그램을 한 번 실행하는 동안 버그가 누락될 확률은 0.4%입니다.

## 요구사항 <a href="#requirements" id="requirements"></a>

[Android 일반 커널](https://android.googlesource.com/kernel/common/)의 최신 버전(4.14 및 이후 버전)은 추가 설정 없이 HWASan을 지원합니다. Android 10의 특정 브랜치는 HWASan을 지원하지 않습니다.

HWASan의 사용자 공간 지원은 Android 11부터 사용할 수 있습니다.

다른 커널을 사용하는 경우 HWASan이 지원되려면 Linux 커널이 시스템 호출 인수에서 태그된 포인터를 받아야 합니다. 이를 위한 지원은 다음 업스트림 패치 세트에 구현되었습니다.

* [arm64 태그된 주소 ABI](https://patchwork.kernel.org/cover/11107499/)
* [arm64: 커널에 전달된 사용자 포인터 태그 취소](https://patchwork.kernel.org/cover/11055001/)
* [mm: brk()/mmap()/mremap()에서 가상 주소 별칭을 만들지 않음](https://patchwork.kernel.org/cover/11391315/)
* [arm64: 커널 스레드에서 호출된 access\_ok()의 태그된 주소 확인](https://patchwork.kernel.org/cover/11275303/)

맞춤 도구 모음을 사용하여 빌드하는 경우에는 LLVM 커밋 [c336557f](https://github.com/llvm/llvm-project/commit/c336557f0238dba72718e499bb345d0dd87305fc)까지 모두 포함되어 있는지 확인해야 합니다.

## HWASan 사용 <a href="#using-hwasan" id="using-hwasan"></a>

다음 명령어를 사용하여 HWASan을 사용하는 전체 플랫폼을 빌드합니다.

```
lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j
```

편의상 [aosp\_coral\_hwasan](https://cs.android.com/android/platform/superproject/+/master:device/google/coral/aosp_coral_hwasan.mk?hl=ko)과 유사하게 제품 정의에 SANITIZE\_TARGET 설정을 추가할 수 있습니다.

AddressSanitizer에 익숙한 사용자의 경우 다음과 같은 여러 빌드 복잡성이 사라집니다.

* make를 두 번 실행할 필요가 없습니다.
* 증분 빌드를 추가 설정 없이 사용할 수 있습니다.
* 사용자 데이터를 플래시할 필요가 없습니다.

다음과 같은 AddressSanitizer 제한도 사라졌습니다.

* 정적 실행 파일이 지원됩니다.
* libc를 제외한 모든 타겟의 제거를 건너뛰어도 괜찮습니다. ASan과 달리, 라이브러리가 제거된 경우 이 라이브러리를 연결하는 모든 실행 파일도 제거되어야 한다는 요구사항이 없습니다.

HWASan 및 동일한(또는 보다 높은) 빌드 번호를 갖는 일반 이미지 간에 자유롭게 전환할 수 있습니다. 기기를 완전 삭제할 필요가 없습니다.

모듈 제거를 건너뛰려면 `LOCAL_NOSANITIZE := hwaddress`(Android.mk) 또는 `sanitize: { hwaddress: false }`(Android.bp)를 사용합니다.

## 개별 타겟 제거 <a href="#sanitizing-individual-targets" id="sanitizing-individual-targets"></a>

HWASan은 `libc.so`도 함께 제거되는 한 일반(제거되지 않은) 빌드에서 타겟별로 사용 설정할 수 있습니다. bionic/libc/Android.bp의 `"libc_defaults"`에 있는 제거 블록에 `hwaddress: true`를 추가합니다. 그런 다음 작업 중인 타겟에서도 동일한 작업을 적용합니다.

libc를 제거하면 시스템 전체의 힙 메모리 할당을 태그할 수 있고 `libc.so` 내부의 메모리 작업 태그를 확인할 수 있습니다. 이를 통해 잘못된 메모리 액세스가 `libc.so`에 있는 경우(예: `delete()`된 뮤텍스의 `pthread_mutex_unlock()`) HWASan이 사용 설정되지 않은 바이너리에서도 버그를 발견할 수 있습니다.

플랫폼 전체가 HWASan을 사용하여 빌드되었다면 빌드 파일을 변경할 필요가 없습니다.

## Flashstation <a href="#flashstation" id="flashstation"></a>

부트로더가 잠금 해제된 Pixel 기기에 HWASan이 사용 설정된 AOSP 빌드를 [Flashstation](https://flash.android.com/?hl=ko)을 사용하여 개발용으로 플래시할 수 있습니다. \_hwasan 타겟(예: aosp\_flame\_hwasan-userdebug)을 선택합니다. 자세한 내용은 앱 개발자를 위한 HWASan [NDK 문서](https://developer.android.com/ndk/guides/hwasan?hl=ko)를 참고하세요.

## 향상된 스택 트레이스 <a href="#better_stack_traces" id="better_stack_traces"></a>

HWASan은 고속 프레임 포인터 기반 언와인더를 사용하여 프로그램의 모든 메모리 할당 및 할당 취소 이벤트에 관한 스택 트레이스를 기록합니다. Android는 기본적으로 AArch64 코드에서 프레임 포인터를 사용 설정하므로 실제로 매우 잘 작동합니다. 관리 코드를 통해 해제해야 하는 경우 프로세스 환경에서 `HWASAN_OPTIONS=fast_unwind_on_malloc=0`을 설정합니다. 잘못된 메모리 액세스 스택 트레이스는 기본적으로 '느린' 언와인더를 사용합니다. 이 설정은 할당 및 할당 취소 트레이스에만 영향을 미칩니다. 이 옵션은 로드에 따라 CPU를 매우 많이 사용할 수 있습니다.

## 기호화 <a href="#symbolization" id="symbolization"></a>

'HWASan 보고서 이해하기'의 [기호화](https://source.android.com/docs/security/test/memory-safety/hwasan-reports?hl=ko#symbolization)를 참고하세요.

## 앱 내 HWASan <a href="#hwasan_in_the_apps" id="hwasan_in_the_apps"></a>

AddressSanitizer와 마찬가지로 HWASan에서는 자바 코드를 볼 수 없지만 JNI 라이브러리에서 버그를 감지할 수 있습니다. ASan과 달리 HWASan 기기 이외의 기기에서는 HWASan 앱을 실행할 수 **없습니다**.

HWASan 기기에서 Make에서는 `SANITIZE_TARGET:=hwaddress`로, 컴파일러 플래그에서는 `-fsanitize=hwaddress`로 앱 코드를 빌드하여 HWASan으로 앱을 확인할 수 있습니다. 자세한 내용은 [앱 개발자 문서](https://developer.android.com/ndk/guides/hwasan?hl=ko#build)를 참조하세요.

## 출처 : [바로가기 ](https://source.android.com/)

{% embed url="<https://doc.skill.or.kr>" %}
NHN Cloud 정보 사이트&#x20;
{% endembed %}

{% embed url="<https://ssv.skill.or.kr>" %}
취약점 진단 분석 평가 방법 사이트
{% endembed %}
