# 태그가 지정된 포인터

## 태그가 지정된 포인터 란?

Android 11부터 64비트 프로세스의 경우 모든 힙 할당에는 ARM Top-byte Ignore(TBI) 커널 지원이 있는 기기에서 포인터의 최상위 바이트에 설정된 구현 정의 태그가 있습니다. 이 태그를 수정하는 모든 애플리케이션은 할당 해제 중에 태그를 확인되면 종료됩니다. 이는 [ARM Memory Tagging Extension](https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/enhancing-memory-safety)(MTE)을 지원하는 향후 하드웨어에 필요합니다.

## Top-byte Ignore <a href="#top-byte-ignore" id="top-byte-ignore"></a>

ARM의 Top-byte Ignore 기능은 모든 Armv8 AArch64 하드웨어에서 64비트 코드에 사용할 수 있습니다. 이 기능은 하드웨어가 메모리에 액세스할 때 포인터의 최상위 바이트를 무시한다는 것을 의미합니다.

TBI에는 사용자 공간에서 전달된 태그가 지정된 포인터를 올바르게 처리하는 [호환 커널](https://www.kernel.org/doc/html/latest/arm64/tagged-address-abi.html#id1)이 필요합니다. 4.14(Pixel 4) 이상의 Android 일반 커널에는 필수 [TBI 패치](https://android-review.googlesource.com/c/kernel/common/+/1132334/)가 포함됩니다.

커널에서 TBI를 지원하는 기기는 프로세스 시작 시간에 동적으로 감지되며 구현 종속 태그는 모든 힙 할당 포인터의 최상위 바이트에 삽입됩니다. 그런 다음 메모리 할당을 해제할 때 태그가 잘리지 않았는지 확인합니다.

## Memory Tagging Extension 준비 <a href="#memory-tagging-extension-readiness" id="memory-tagging-extension-readiness"></a>

ARM의 Memory Tagging Extension(MTE)은 메모리 안전 문제를 해결하는 데 도움이 됩니다. MTE는 스택, 힙, 전역에서 각 메모리 할당의 56번째\~59번째 주소 비트를 **태그**하여 작동합니다. 하드웨어와 명령 집합은 메모리 액세스 시마다 올바른 태그가 사용되는지 자동으로 확인합니다.

포인터의 최상위 바이트에 정보를 잘못 저장하는 Android 앱은 **MTE 지원 기기에서 작동이 중단됩니다**. 태그가 지정된 포인터를 사용하면 MTE 기기를 사용하기 전에 포인터의 최상위 바이트를 잘못 사용하는 것을 더 쉽게 감지하여 거부할 수 있습니다.

## 개발자 지원 <a href="#developer-support" id="developer-support"></a>

{% hint style="info" %}
참고: 64비트 버전의 앱을 테스트해야 태그가 지정된 포인터 문제를 재현할 수 있습니다.
{% endhint %}

앱이 비정상 종료되고 이 링크가 표시되는 경우 다음 중 하나가 원인일 수 있습니다.

1. 애플리케이션이 시스템의 힙 할당자에서 할당하지 않은 포인터를 해제하려고 했습니다.
2. 앱의 어떤 부분이 포인터의 최상위 바이트를 수정했습니다. 포인터의 최상위 바이트는 수정할 수 없고 코드를 변경하여 이 문제를 해결해야 합니다.

잘못 사용되거나 수정되는 최상위 바이트 포인터의 예는 다음과 같습니다.

* 특정 유형 포인터에는 최상위 16개 주소 비트에 저장된 애플리케이션별 메타데이터가 있습니다.
* 포인터가 double로 전송되었다가 돌아오므로 하위 주소 비트가 손실됩니다.
* 재귀 깊이를 측정하는 방법으로 다양한 스택 프레임에서 로컬 변수 주소 간의 차이를 계산하는 코드입니다.

일부 애플리케이션은 포인터의 최상위 바이트가 설정될 때 잘못 동작하는 라이브러리에 의존할 수 있습니다. 라이브러리의 이러한 기본 문제를 빠르게 해결하기는 쉽지 않은 일일 수 있습니다. 따라서 `targetSdkLevel < 30`을 사용하는 애플리케이션에는 기본적으로 포인터 태그 지정이 사용 설정되지 않습니다. `targetSdkLevel >= 30`으로 빌드된 애플리케이션의 전환기가 수월하도록 이스케이프 해치도 제공합니다.

이스케이프 해치는 `AndroidManifest.xml` 파일에 다음을 추가하여 사용합니다.

```
  <application android:allowNativeHeapPointerTagging="false">
  ...
  </application>
```

이렇게 하면 애플리케이션의 포인터 태그 지정 기능이 사용 중지됩니다. 기본 코드 상태 문제는 해결되지 **않습니다**. 이 이스케이프 해치는 향후 Android 버전에서 사라집니다. 이러한 성격의 문제가 [MTE](https://security.googleblog.com/2019/08/adopting-arm-memory-tagging-extension.html)와 호환되지 않기 때문입니다.

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

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

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