security
CHAPTER 94 / 96
읽기 약 2분
FUNCTION
정수 오버플로우의 수학
핵심 개념
signed/unsigned 범위·오버플로우 → 뜻밖의 값. 이더리움 BatchOverflow + SafeMath.
본문
정수 타입 범위
// 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)오버플로우 데모
#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;
}곱셈 오버플로우
#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 코드 — 정수 오버플로우 사례
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 패턴 (방어)
#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 안전 산술
#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;
}컴파일 시 검사
# 정수 오버플로우 탐지 (런타임)
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실전 — 메모리 할당 크기 검증
#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