Skip to content

[BUG] Use-After-Free in DynamicArray Move Constructor due to Allocator Transfer Failure #25

@Winteradio

Description

@Winteradio

Open · Winteradio opened this issue on March 5, 2026

⚠️ Issue Description

DynamicArray의 이동 생성자(Move Constructor) 수행 시, m_data 포인터는 정상적으로 이동되나 m_allocator가 이동되지 않는 결함이 발견되었습니다.

이로 인해 이동의 대상이 된 객체(other)가 스코프를 벗어나 소멸할 때, other가 여전히 소유권을 주장하고 있는 할당자가 파괴되거나 잘못된 동작을 수행하여 이미 이동된 m_data의 메모리까지 해제해버리는 현상이 발생합니다.

❌ Problematic Code (Before)

m_allocator를 이동시키지 않아 other 객체가 소멸할 때 할당자 관련 사이드 이펙트가 발생했습니다.

DynamicArray(DynamicArray&& other) noexcept
    : m_data(std::move(other.m_data))
    , m_size(std::move(other.m_size))
    , m_capacity(std::move(other.m_capacity))
    // m_allocator가 누락됨! 
{
    other.m_data = nullptr;
    other.m_size = 0;
    other.m_capacity = 0;
}

✅ Fixed Code (After)

할당자 또한 std::move를 통해 명시적으로 소유권을 이전하도록 수정하였습니다.

DynamicArray(DynamicArray&& other) noexcept
    : m_data(std::move(other.m_data))
    , m_size(std::move(other.m_size))
    , m_capacity(std::move(other.m_capacity))
    , m_allocator(std::move(other.m_allocator)) // 할당자 소유권 이전 추가
{
    other.m_data = nullptr;
    other.m_size = 0;
    other.m_capacity = 0;
    // stateful 할당자일 경우 other의 할당자 상태도 초기화 필요할 수 있음
}

🔍 Technical Analysis

  1. Stateful Allocator Issue: 원목님이 사용 중인 Arena와 같은 커스텀 할당자는 상태(State)를 가집니다. 할당자를 복사하거나 이동하지 않으면, 새 객체는 기본 생성된 할당자를 가지게 되어 기존 메모리(m_data)에 대한 해제 권한이 없거나 잘못된 메모리 풀을 참조하게 됩니다.
  2. Double Free / Dangling Pointer: other 객체의 소멸자가 호출될 때, other.m_allocator가 자신이 관리하던 메모리 블록을 정리하려고 시도합니다. 이때 이미 m_data는 새 객체로 넘어갔음에도 불구하고 메모리가 해제되어 Use-After-Free 또는 Double Free가 발생합니다.

💡 Note

이동 생성자뿐만 아니라 **이동 대입 연산자(Move Assignment Operator)**에서도 동일한 로직이 적용되어 있는지 확인이 필요합니다. 할당자가 상태를 가진다면 반드시 데이터와 운명을 함께해야 합니다.


Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions