OPEN HYPER STEP
← 목록으로 (화이트햇 보안)
SECURITY · 94 / 96
security
CHAPTER 94 / 96
읽기 약 2
FUNCTION

정수 오버플로우의 수학


핵심 개념

signed/unsigned 범위·오버플로우 → 뜻밖의 값. 이더리움 BatchOverflow + SafeMath.

본문

정수 타입 범위

C📋 코드 (9줄)
// 32-bit signed int
INT_MIN = -2,147,483,648  (-2^31)
INT_MAX =  2,147,483,647  ( 2^31 - 1)

// 32-bit unsigned int
UINT_MAX = 4,294,967,295  ( 2^32 - 1)

// 64-bit signed long long
LLONG_MAX = 9,223,372,036,854,775,807  (2^63 - 1)

오버플로우 데모

C📋 코드 (18줄)
#include <stdio.h>
#include <limits.h>

int main(void) {
    int max = INT_MAX;
    printf("INT_MAX = %d\n", max);              // 2147483647
    printf("INT_MAX + 1 = %d\n", max + 1);      // -2147483648 (음수로!)

    unsigned u = 0;
    printf("0 - 1 (unsigned) = %u\n", u - 1);   // 4294967295 (UINT_MAX)

    short s = 32767;
    printf("32767 + 1 (short) = %d\n", s + 1);  // -32768

    // 보통 컴파일러 경고:
    // warning: integer overflow in expression
    return 0;
}

곱셈 오버플로우

C📋 코드 (16줄)
#include <stdio.h>
#include <limits.h>

int main(void) {
    int a = 100000;
    int b = 100000;
    int result = a * b;  // 10^10 > INT_MAX
    printf("%d * %d = %d\n", a, b, result);
    // 결과: 10^10 → wrap around → 음수 또는 작은 값
    // → 정의되지 않은 동작 (signed overflow)

    // 안전:
    long long safe = (long long)a * b;
    printf("(long long): %lld\n", safe);  // 10000000000
    return 0;
}

이더리움 BatchOverflow (CVE-2018-10299)

SOLIDITY📋 코드 (17줄)
// ⚠️ Solidity 코드 — 정수 오버플로우 사례
function batchTransfer(address[] _receivers, uint256 _value) public {
    uint cnt = _receivers.length;
    uint256 amount = uint256(cnt) * _value;  // ⚠️ 오버플로우!

    require(_value > 0 && balances[msg.sender] >= amount);
    // amount가 오버플로우로 작아짐 → 검사 우회

    balances[msg.sender] -= amount;
    for (uint i = 0; i < cnt; i++) {
        balances[_receivers[i]] += _value;  // 실제 전송은 그대로
    }
}

// 공격: cnt=2, _value=2^255
// amount = 2 * 2^255 → 오버플로우 → 0
// 잔액 검사 통과 → 거대 금액 송금 → 시장 가치 폭락

SafeMath 패턴 (방어)

C📋 코드 (36줄)
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>

// 안전 곱셈
bool safe_mul(int a, int b, int *result) {
    if (a == 0 || b == 0) {
        *result = 0;
        return true;
    }
    if (a > INT_MAX / b || a < INT_MIN / b) {
        return false;  // 오버플로우
    }
    *result = a * b;
    return true;
}

// 안전 덧셈
bool safe_add(int a, int b, int *result) {
    if ((b > 0 && a > INT_MAX - b) ||
        (b < 0 && a < INT_MIN - b)) {
        return false;
    }
    *result = a + b;
    return true;
}

int main(void) {
    int r;
    if (safe_mul(100000, 100000, &r)) {
        printf("성공: %d\n", r);
    } else {
        printf("오버플로우 감지\n");
    }
    return 0;
}

GCC built-in 안전 산술

C📋 코드 (20줄)
#include <stdio.h>
#include <stdint.h>

int main(void) {
    int a = 100000, b = 100000, result;

    // GCC built-in (gcc 5+)
    if (__builtin_mul_overflow(a, b, &result)) {
        printf("오버플로우 감지\n");
    } else {
        printf("결과: %d\n", result);
    }

    // 다른 함수:
    // __builtin_add_overflow
    // __builtin_sub_overflow
    // __builtin_mul_overflow
    // 모두 오버플로우 시 true 반환
    return 0;
}

컴파일 시 검사

BASH📋 코드 (12줄)
# 정수 오버플로우 탐지 (런타임)
gcc -fsanitize=undefined,signed-integer-overflow prog.c
./prog

# 출력 (오버플로우 시):
# prog.c:10:19: runtime error: signed integer overflow:
#   2147483647 + 1 cannot be represented in type 'int'


# 정적 분석
clang --analyze prog.c
# 또는 cppcheck, scan-build

실전 — 메모리 할당 크기 검증

C📋 코드 (28줄)
#include <stdio.h>
#include <stdlib.h>

void *safe_calloc(size_t count, size_t size) {
    // size_t 곱 오버플로우 검사
    if (count != 0 && size > SIZE_MAX / count) {
        return NULL;  // 오버플로우
    }
    return calloc(count, size);
}


int main(void) {
    // ❌ 위험 — 곱이 작아져 작은 메모리 할당
    // 이후 큰 데이터 쓰기 → 힙 오버플로우
    size_t n = 1000000000;
    size_t s = 100;
    // void *p = malloc(n * s);  // 1e11 → wrap

    // ✅ 안전
    void *p = safe_calloc(n, s);
    if (!p) {
        fprintf(stderr, "할당 실패 (오버플로우 또는 OOM)\n");
        return 1;
    }
    free(p);
    return 0;
}

다음 챕터

CH.11 "ASLR, DEP, Stack Canary" — 현대 방어 기법 3종.


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

내 C 코드의 모든 곱셈·덧셈 위치를
분석해서 정수 오버플로우 가능한 위치와
SafeMath 적용 우선순위를 만들어줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

실제 CVE에서 정수 오버플로우 5개 사례
(이더리움/리눅스 커널/브라우저)를
비교 분석해줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 코드베이스에 -fsanitize=undefined +
__builtin_*_overflow 적용 + CI 통합
가이드를 만들어줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 정수 오버플로우 관련 CVE 빈도와
Rust의 checked arithmetic 비교를
솔직히 알려줘.

⭐ 이것만 기억하세요
정수 오버플로우의 수학 이 3가지만 확실히 잡으세요
1.정수 오버플로우는 wrap around — INT_MAX + 1 = INT_MIN 같은 직관과 다른 결과
2.SafeMath 또는 __builtin_*_overflow + UBSan으로 모든 오버플로우 탐지
3.다음 챕터 CH.11에서 ASLR/DEP/Stack Canary — 현대 OS의 방어 기법


공유하기
진행도 94 / 96