문제의 역사
안전한 메모리 복사는 C에서 가장 자주 발생하는 중요한 작업 중 하나입니다. 처음에는 프로그램들이 바이트 단위로 복사하기 위해 루프를 사용했습니다. 이후 표준 함수인 memcpy, memmove가 추가되었으며, 문자열을 위한 더 안전한 대안인 strncpy와 같은 함수도 추가되었습니다. 잘못된 복사는 버퍼 오버플로우 및 취약점으로 이어질 수 있습니다.
문제
부적절한 함수를 사용하거나 복사할 때 잘못된 크기를 지정하면 데이터가 손상될 수 있으며, 심지어 보안 관심이 있는 제3자가 데이터를 얻을 수 있는 경로를 열 수 있습니다. 메모리 영역이 겹치는 경우에 memmove를 사용해야 할 때와 memcpy를 사용할 수 있는 경우를 구분하는 것이 오류를 피하는 데 원칙적으로 중요합니다.
해결책
비문자 메모리를 안전하게 복사하려면 다음을 사용하십시오:
memcpy(dest, src, n);
memcpy는 src에서 dest로 n 바이트를 빠르게 복사합니다. 단, 이들 메모리 영역이 겹쳐서는 안 됩니다.memmove를 사용하십시오:memmove(dest, src, n);
문자열을 복사하려면 strncpy 또는 더 좋게는 사용 가능한 경우에 현대적이고 안전한 대안인 strlcpy를 사용하는 것이 좋습니다.
주요 특징들:
memcpy는 src와 dest의 겹침이 없을 때만 안전합니다.memmove는 겹치는 메모리 영역에서도 올바르게 작동합니다.1. memcpy와 memmove의 차이점은 무엇이며 어떤 경우에 어떤 함수가 필요합니까?
memcpy는 매우 빠르게 작동하지만 겹치는 메모리 영역을 염두에 두지 않습니다. 결과는 예측할 수 없습니다. memmove는 겹침에 관계없이 올바른 복사를 보장합니다:
int arr[] = {1,2,3,4,5}; // memmove: 겹침이 있을 때 안전하게 복사 memmove(arr+1, arr, 4 * sizeof(int));
2. 복사할 문자열의 버퍼가 더 작을 때 strcpy를 사용해도 안전합니까?
아니요, strcpy 함수는 대상 버퍼의 크기를 확인하지 않습니다. 이는 종종 버퍼 오버플로우를 초래합니다. strncpy 또는 strlcpy (가능할 경우)를 사용하거나 크기를 명시적으로 제어하는 것이 좋습니다:
char dest[5]; strncpy(dest, src, sizeof(dest)-1); // src는 5자보다 짧아야 합니다.
3. 구조체를 포인터와 함께 memcpy로 복사할 수 있습니까?
가능하지만, 이 경우는 포인터만 복사되고 해당 주소의 데이터는 복사되지 않습니다. 이는 메모리 작업 중 오류 및 이중 해제를 초래할 수 있습니다.
길이가 긴 문자열을 체크 없이 strcpy로 작은 버퍼에 복사합니다. 버퍼 오버플로우가 발생하여 취약점이 생깁니다.
장점:
단점:
정확한 크기 제어를 통해 strncpy 또는 memmove를 사용하며, 수동으로 문자열의 널 종료 문자를 보장합니다.
장점:
단점: