# Scudo

## Scudo 란?

Scudo는 동적 사용자 모드 메모리 할당자 또는 *힙* 할당자로, 힙 관련 취약점(예: [힙 기반 버퍼 오버플로](https://cwe.mitre.org/data/definitions/122.html), [use after free](https://cwe.mitre.org/data/definitions/416.html), [double free](https://cwe.mitre.org/data/definitions/415.html))으로부터 보호하고 성능을 유지하기 위해 설계되었습니다. 표준 C 할당 및 할당 해제 프리미티브(예: [malloc](http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html) 및 free)와 C++ 프리미티브(예: new 및 delete)도 제공합니다.

Scudo는 [AddressSanitizer(ASan)](https://source.android.com/devices/tech/debug/sanitizers?hl=ko#addresssanitizer)와 같은 전문적인 메모리 오류 감지기보다 완화에 더 중점을 둔 할당자입니다.

Android 11 출시부터는 모든 네이티브 코드에 scudo가 사용됩니다(jemalloc이 여전히 사용되는 메모리 용량이 낮은 기기 제외). 런타임 시 모든 네이티브 힙 할당 및 할당 해제가 Scudo에서 모든 실행 파일 및 파일의 라이브러리 종속 항목에 제공되며 힙에서 손상이나 의심스러운 동작이 감지되면 프로세스가 중단됩니다.

Android 10에서 scudo는 .mk 파일의 `LOCAL_SANITIZE := scudo` 옵션이나 .bp 파일의 `sanitize: { scudo: true, }`를 설정하여 바이너리별로 사용 설정해야 했습니다.

Scudo는 [오픈소스](https://github.com/llvm/llvm-project/tree/main/compiler-rt/lib/scudo)이며 LLVM의 compiler-rt 프로젝트의 일부입니다. 관련 문서는 <https://llvm.org/docs/ScudoHardenedAllocator.html>에서 확인할 수 있습니다. Scudo 런타임은 Android 도구 모음의 일부로 제공되며 [Soong 및 Make](https://android.googlesource.com/platform/build/soong/)가 지원되어 바이너리에서 Scudo를 쉽게 사용 설정할 수 있습니다.

아래에 설명된 옵션을 사용하여 Scudo 내에서 추가 완화를 사용 설정하거나 사용 중지할 수 있습니다.

## 맞춤설정 <a href="#customization" id="customization"></a>

할당자의 일부 매개변수는 다음과 같은 여러 방법을 통해 프로세스별로 정의할 수 있습니다.

* **정적:** 파싱할 옵션 문자열을 반환하는 프로그램의 `__scudo_default_options` 함수를 정의합니다. 이 함수에는 `extern "C" const char *__scudo_default_options()` 프로토타입이 있어야 합니다.
* **동적:** 파싱할 옵션 문자열을 포함하는 `SCUDO_OPTIONS` 환경 변수를 사용합니다. 이 방식으로 정의된 옵션은 `__scudo_default_options`를 통해 만들어진 모든 정의보다 우선합니다.

사용할 수 있는 옵션은 다음과 같습니다.

{% hint style="info" %}
참고: 프런트엔드 옵션의 이름 형식은 백엔드 옵션과 다릅니다.
{% endhint %}

<table><thead><tr><th width="211">옵션</th><th width="136">64비트 기본값</th><th width="137">32비트 기본값</th><th>설명</th></tr></thead><tbody><tr><td><code>QuarantineSizeKb</code></td><td><code>256</code></td><td><code>64</code></td><td>청크의 실제 할당 해제를 지연하는 데 사용되는 스팸 격리 저장소의 크기(KB)입니다. 값이 낮을수록 메모리 사용량은 줄지만 완화 효과가 감소할 수 있습니다. 음수 값은 기본값으로 대체됩니다. 이 값과 <code>ThreadLocalQuarantineSizeKb</code>를 0으로 설정하면 스팸 격리 저장소가 완전히 사용 중지됩니다.</td></tr><tr><td><code>QuarantineChunksUpToSize</code></td><td><code>2048</code></td><td><code>512</code></td><td>청크를 격리할 수 있는 최대 크기(바이트)입니다.</td></tr><tr><td><code>ThreadLocalQuarantineSizeKb</code></td><td><code>64</code></td><td><code>16</code></td><td>전역 스팸 격리 저장소를 오프로드하는 데 사용하는 스레드당 캐시 크기(KB)입니다. 값이 낮을수록 메모리 사용량은 줄지만 전역 스팸 격리 저장소에서의 경합이 증가할 수 있습니다. 이 값과 <code>QuarantineSizeKb</code>를 0으로 설정하면 스팸 격리 저장소가 완전히 사용 중지됩니다.</td></tr><tr><td><code>DeallocationTypeMismatch</code></td><td><code>false</code></td><td><code>false</code></td><td>malloc/delete, new/free, new/delete[] 오류 신고를 사용 설정합니다.</td></tr><tr><td><code>DeleteSizeMismatch</code></td><td><code>true</code></td><td><code>true</code></td><td>new와 delete의 크기가 일치하지 않는 경우 오류 신고를 사용 설정합니다.</td></tr><tr><td><code>ZeroContents</code></td><td><code>false</code></td><td><code>false</code></td><td>할당 및 할당 해제 시 0개의 청크 콘텐츠를 사용 설정합니다.</td></tr><tr><td><code>allocator_may_return_null</code></td><td><code>false</code></td><td><code>false</code></td><td>복구가 가능한 오류가 발생할 때 프로세스를 종료하는 대신 할당자가 null을 반환할 수 있도록 지정합니다.</td></tr><tr><td><code>hard_rss_limit_mb</code></td><td><code>0</code></td><td><code>0</code></td><td>프로세스의 RSS가 이 한도에 도달하면 프로세스가 종료됩니다.</td></tr><tr><td><code>soft_rss_limit_mb</code></td><td><code>0</code></td><td><code>0</code></td><td>프로세스의 RSS가 이 한도에 도달하면 다시 새로운 할당을 허용할 때까지 <code>allocator_may_return_null</code>의 값에 따라 추가 할당이 실패하거나 <code>null</code>을 반환합니다.</td></tr><tr><td><code>allocator_release_to_os_interval_ms</code></td><td>N/A</td><td><code>5000</code></td><td>64비트 할당자에만 영향을 줍니다. 이 옵션을 설정하면 사용되지 않는 메모리를 OS로 릴리스하려고 시도하지만 이 간격(밀리초)보다 더 짧은 간격으로 시도하지는 않습니다. 값이 음수이면 메모리가 OS로 릴리스되지 않습니다.</td></tr><tr><td><code>abort_on_error</code></td><td><code>true</code></td><td><code>true</code></td><td>이 옵션을 설정하면 도구에서 오류 메시지를 인쇄한 후 <code>_exit()</code> 대신 <code>abort()</code>를 호출합니다.</td></tr></tbody></table>

## 유효성 검사 <a href="#validation" id="validation"></a>

현재 Scudo 전용 CTS 테스트는 없습니다. 그 대신 CTS 테스트가 특정 바이너리에 Scudo를 사용하거나 사용하지 않고 통과하도록 하여 Scudo가 기기에 영향을 주지 않음을 검증합니다.

## 문제 해결 <a href="#troubleshooting" id="troubleshooting"></a>

복구할 수 없는 문제가 감지되면 할당자는 표준 오류 설명자에 오류 메시지를 표시한 다음 프로세스를 종료합니다. 종료를 유발하는 스택 트레이스가 시스템 로그에 추가됩니다. 출력은 일반적으로 `Scudo ERROR:`로 시작되며 이어서 포인터와 함께 문제가 간략하게 요약된 내용이 나옵니다.

{% hint style="info" %}
참고: Scudo는 완화를 목적으로 합니다. 문제의 근본 원인을 파악하려면 ASan을 사용해 보시기 바랍니다.
{% endhint %}

다음은 현재 오류 메시지와 그 잠재적 원인의 목록입니다.

* `corrupted chunk header`: 청크 헤더의 체크섬 검증에 실패했습니다. 헤더가 부분적으로 또는 완전히 덮어쓰였거나 함수에 전달된 포인터가 청크가 아니기 때문일 수 있습니다.
* `race on chunk header`: 두 개의 다른 스레드가 같은 헤더를 동시에 조작하려고 합니다. 이는 대개 청크에서 연산을 실행할 때 경합 상태이거나 전반적으로 잠금이 없다는 것을 의미합니다.
* `invalid chunk state`: 특정 연산에서 청크가 예상되는 상태가 아닙니다. 예를 들어 청크를 해제하려고 할 때 할당되지 않거나, 청크를 재활용하려고 할 때 격리되지 않습니다. double free가 이 오류의 일반적인 원인입니다.
* `misaligned pointer`: 기본 정렬 요구사항이 강력하게 적용됩니다. 32비트 플랫폼에서는 8바이트, 64비트 플랫폼에서는 16바이트입니다. 함수에 전달된 포인터가 요구사항에 맞지 않으면 함수 중 하나에 전달된 포인터가 정렬되지 않습니다.
* `allocation type mismatch`: 이 옵션을 사용하면 청크에서 호출되는 할당 해제 함수는 할당을 위해 호출된 함수의 유형과 일치해야 합니다. 이러한 유형의 불일치는 보안 문제를 일으킬 수 있습니다.
* `invalid sized delete`: C++14로 크기가 조정된 delete 연산자를 사용하고 선택적 검사를 사용 설정하면 청크를 할당 해제할 때 전달된 크기와 할당할 때 요청된 크기 간의 불일치가 발생합니다. 이러한 불일치는 일반적으로 컴파일러 문제이거나 할당 해제되는 객체 [유형의 혼동](https://cwe.mitre.org/data/definitions/843.html)으로 인해 발생합니다.
* `RSS limit exhausted`: 선택적으로 지정한 RSS의 최댓값을 초과했습니다.

OS 자체에서 비정상 종료를 디버깅하는 경우 [HWASan OS 빌드](https://source.android.com/devices/tech/debug/hwasan?hl=ko)를 사용할 수 있습니다. 앱에서 비정상 종료를 디버깅하는 경우 [HWASan 앱 빌드](https://developer.android.com/ndk/guides/hwasan?hl=ko)도 사용할 수 있습니다.

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

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

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sul.skill.or.kr/android-security-test/scudo.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
