[하루한줄] CVE-2023-6779/CVE-2023-6780: glibc Heap Buffer Overflow와 패치된 코드의 Integer Overflow
URL
syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6779)
syslog: Fix integer overflow in __vsyslog_internal (CVE-2023-6780)
Target
- glibc 2.36 이상
Explain
GNU C library인 glibc에서 발견된 Heap Buffer Overflow 취약점 및 패치된 코드의 추가적인 Integer Overflow 취약점의 세부 정보가 공개되었습니다.
첫 번째 취약점(CVE-2023-6779)은 syslog.c
파일의 __vsyslog_internal
함수에서 snprintf
/vsnprintf
를 사용하며 메모리 할당 사이즈를 계산하는 과정에서 발생합니다.
void __vsyslog_internal (int pri, const char *fmt, va_list ap, unsigned int mode_flags)
{
//...
vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags); // (1)
if (!(0 <= vl && vl < len))
buf = NULL;
bufsize = l + vl; // (2)
va_end (apc);
}
if (buf == NULL)
{
buf = malloc ((bufsize + 1) * sizeof (char)); // (3)
//...
__vsnprintf_internal
함수는 copy한 크기를 리턴하며, 함수 호출에 실패하면-1
를 반환합니다.- 취약한 코드는 리턴값을
vl
에 저장하므로 함수 호출 실패 시vl
이-1
이 될 수 있습니다.
- 취약한 코드는 리턴값을
bufsize
는vl
을 이용해 계산되기 때문에 예상보다 작게 계산됩니다.bufsize+1
만큼 할당되는buf
가 예상보다 작게 할당돼 이후buf
에 copy하는 과정에서 Heap Buffer Overflow가 트리거될 수 있습니다.
CVE-2023-6779 취약점은 아래와 같이 vl
이 0
보다 작은 경우 더 이상 메모리 할당 및 copy를 진행하지 않는 것으로 이루어졌습니다.
void __vsyslog_internal (int pri, const char *fmt, va_list ap, unsigned int mode_flags)
{
//...
vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
va_end (apc);
if (vl < 0)
goto out;
if (vl >= len)
buf = NULL;
bufsize = l + vl;
}
if (buf == NULL)
{
buf = malloc ((bufsize + 1) * sizeof (char));
//...
그러나 위 패치된 코드에서도 추가로 Integer Overflow 취약점이 발견되어 CVE-2023-6780이 할당되었습니다.
vl
이 INT_MAX
값보다 큰 경우 이를 검증하는 코드가 없어 발생하는 Integer Overflow 취약점으로, CVE-2023-6779와 마찬가지로 bufsize 계산에 영향을 주어 이후 Heap Buffer Overflow로 이어질 수 있습니다.
최종적으로 vl
이 INT_MAX - 1
이상인지 검증하는 코드를 추가하는 것으로 패치가 이루어졌습니다.
void __vsyslog_internal (int pri, const char *fmt, va_list ap, unsigned int mode_flags)
{
//...
vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
va_end (apc);
if (vl < 0 || vl >= INT_MAX - 1)
goto out;
if (vl >= len)
buf = NULL;
bufsize = l + vl;
}
if (buf == NULL)
{
buf = malloc ((bufsize + 1) * sizeof (char));
//...
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.