설명
힙 버퍼 크기가 복사 길이를 수용한다는 보장 없이 고정 크기 또는 계산된 데이터를 복사하면 힙을 넘겨쓸 수 있습니다.
잠재적 영향
- 힙 메타데이터 손상, 크래시, 임의 코드 실행 가능성이 있습니다.
해결 방법
할당 크기와 복사 길이를 같은 검증된 값에서 계산하고, 복사 전에 목적지 용량을 확인합니다.
예시
변경 전
c
/* width, height, data_len은 size_t이고 data는 data_len바이트를 가리킵니다. */
struct Image img = load_image();
int size = img.width + img.height;
char *buf = malloc(size);
memcpy(buf, img.data, sizeof(img.data));
변경 후
c
struct Image img = load_image();
const size_t bytes_per_element = 4;
size_t elements;
if (img.width > SIZE_MAX - img.height) { return; }
elements = img.width + img.height;
if (elements > SIZE_MAX / bytes_per_element) { return; }
size_t capacity = elements * bytes_per_element;
if (img.data_len > capacity) { return; }
unsigned char *buf = malloc(capacity);
if (buf == NULL) { return; }
memcpy(buf, img.data, img.data_len);
설명:
- 변경 전: 계산된 할당 크기
size와 실제 복사 길이의 관계를 확인하지 않습니다.img.data가 포인터이면sizeof(img.data)는 데이터 전체 길이가 아니라 포인터 크기입니다. - 변경 후:
width,height,data_len을size_t로 제공한다고 명시하고, 덧셈과 바이트 수 곱셈을 각각SIZE_MAX에 대해 검사합니다. 실제 소스 길이data_len이 계산된 용량 이하인지와 할당 성공 여부를 확인한 뒤 검증한 바이트 수만 복사합니다. 포인터일 수 있는img.data에sizeof를 적용하지 않습니다.