CVE-2023-6246 / Qualys Advisory

CVE-2023-6246: Glibc __vsyslog_internal Heap Buffer Overflow Teardown

How an off-by-one calculation in Glibc's syslog logging routine allowed local users to overwrite heap buffers via su or sudo, achieving root privileges.

💡 비유를 통한 쉬운 설명 (ELI5)

Imagine a mail room clerk who measures packages before putting them in boxes. If a package is 10 inches, he grabs a 10-inch box. But he forgot that the company always slaps a 3-inch shipping label on top! When he shoves the package into the box, it tears through the sides and crushes the fragile master safe sitting on the shelf next to it.

핵심 개념 및 서브시스템 용어 해설

GNU C Library (Glibc)
The fundamental core library providing the standard C runtime for nearly all Linux distributions.
__vsyslog_internal()
The internal Glibc function responsible for formatting and sending diagnostic messages to the system logging daemon.
Heap Overflow
Writing bytes past the allocated boundary of a dynamically allocated heap memory chunk.
argv[0] Manipulation
Passing an unusually large process invocation name to an executable, altering the prefix in syslog output.

단계별 공격 실행 메커니즘

Step 1

1. Process Invocation with Huge Name

The attacker invokes a setuid binary like su with a 1024-byte argv[0] string.

Step 2

2. Triggering Error Logging

The attacker provides invalid credentials, prompting syslog() to format an error message.

Step 3

3. Buffer Undersizing in vsyslog

__vsyslog_internal() calculates the buffer size without properly accounting for the long program name.

Step 4

4. Heap Memory Corruption

The formatted message overflows into neighboring heap metadata, executing attacker shellcode as root.

소스 코드 비교: 치명적 취약점 vs 보안 강화 패치

일반 개발자가 쉽게 이해할 수 있는 고수준 소스 코드로 제공 (어셈블리/바이너리 제외).

패치되지 않은 취약점
// VULNERABLE: sysdeps/posix/syslog.c before patch
int __vsyslog_internal(int pri, const char *fmt, va_list ap, unsigned int mode_flags) {
    size_t l = strlen(program_invocation_short_name);
    // ROOT CAUSE:
    // When reallocating the log buffer, the code adds 'l' to the length,
    // but under multi-threaded logging or long format strings, 'l' is truncated!
    char *buf = malloc(l + 1024);
    if (!buf) return -1;
    
    // Writes formatted string into undersized buffer!
    int len = vsnprintf(buf, l + 1024, fmt, ap);
    return len;
}
보안 강화 패치
// SECURE: sysdeps/posix/syslog.c patch
int __vsyslog_internal(int pri, const char *fmt, va_list ap, unsigned int mode_flags) {
    size_t l = strlen(program_invocation_short_name);
    
    // 1. Explicitly verify integer overflow bounds before allocating
    size_t total_size;
    if (__builtin_add_overflow(l, 1024, &total_size)) {
        return -1; // Reject dangerous oversized buffer
    }
    
    char *buf = malloc(total_size);
    if (!buf) return -1;
    
    // 2. Pass strictly validated total_size to vsnprintf
    int len = vsnprintf(buf, total_size, fmt, ap);
    return len;
}

엔지니어링 보안 강화 체크리스트

← 전체 보안 디렉터리 보기 모든 플랫폼 보안 업데이트 →