[CVE] CVE 분석 · 작성: 2026-07-20 03:10:34 · 수정: 2026-07-21 23:19:31 · 조회 24
sudoedit -s/sudo -s 같은 셸 모드 호출에서 인자의 백슬래시 이스케이프를 처리하는 로직의 길이 계산이 실제 쓰기 루프와 어긋나서, setuid root로 실행 중인 sudo 프로세스의 힙 버퍼를 오버플로우시킬 수 있다.패치는 plugins/sudoers/sudoers.c의 set_cmnd()(및 관련 유틸리티 함수)에서 이스케이프 카운팅과 실제 버퍼 쓰기 루프의 길이 계산을 일치시키는 것으로 요약된다.
Before
size_t new_size = 0;
for (i = 0; i < argc; i++) {
char *arg = argv[i];
// 셸 모드에서 백슬래시를 이스케이프 처리할 때 필요한 추가 길이를 계산
new_size += strlen(arg) + 1;
if (shell_mode) {
// 특정 조건(인자가 이스케이프 안 된 백슬래시로 끝나는 경우)에서
// 실제로 필요한 이스케이프 문자 수보다 적게 계산되는 경로가 있었음
new_size += count_chars_needing_escape(arg);
}
}
user_args = malloc(new_size);
Before
for (i = 0; i < argc; i++) {
// 이스케이프 처리하며 실제로 써넣는 바이트 수는 원본 인자 길이·내용에 따라 결정됨
to = fill_args_with_escaping(to, argv[i]);
// ↑ 위에서 과소 계산된 new_size를 넘어서는 경우 여기서 힙 버퍼 경계를 넘어 씀
}
"필요한 크기를 계산하는 코드"와 "실제로 그 버퍼에 쓰는 코드"가 서로 다른 조건 분기를 타면서, 특정 인자 조합(셸 모드 + 끝나지 않은 이스케이프 시퀀스)에서 계산된 new_size보다 실제 쓰기 양이 많아지는 불일치가 발생했다.
After (1.9.5p2 / 1.8.32)
size_t new_size = 0;
for (i = 0; i < argc; i++) {
// 계산 로직과 쓰기 로직이 공유하는 단일 이스케이프 카운팅 함수로 통합
new_size += calc_escaped_length(argv[i], shell_mode);
}
user_args = malloc(new_size);
for (i = 0; i < argc; i++) {
to = fill_args_with_escaping(to, argv[i]); // 동일한 calc_escaped_length 기준을 공유
}
크기 계산과 실제 쓰기가 같은 이스케이프 카운팅 함수를 공유하도록 리팩터링해서, 두 로직이 서로 다르게 계산할 여지 자체를 제거했다.
sudoedit -s 등 셸 모드 호출 방식과, 끝이 이스케이프 안 된 백슬래시로 끝나는 인자 조합을 준비set_cmnd()에서 이 인자들을 처리하며 이스케이프 카운팅이 어긋나 힙 버퍼를 과소 할당