munmap 예제

아래의 모든 것은 이 원시적인 것을 기반으로 하지만, 간결하게 하기 위해, 부패와 후속 자유를 모방하는 대신 문맵을 직접 사용하십시오. Linux 페이지 오류 처리기는 크기가 RLIMIT_STACK에 도달할 때까지 스택을 확장하기 위한 특별한 경우가 있습니다. 기본적으로 스택의 시작 부분 아래에 있지만 RSTACK_LIMIT 내에 있는 주소에서 페이지 오류가 발생할 때마다 스택은 주소가 포함된 페이지까지 확장됩니다. 이렇게 하면 스택의 일부를 매핑 해제하고 커널이 다음 액세스 시 0 페이지로 마술처럼 다시 매핑하도록 할 수 있습니다. 몇 가지 실험 및 커널 소스 읽기 후, 그것은 스택의 모든 페이지, 맨 위를 제외 하 고, 공정한 게임 것 같다. 내 생각엔 이것이 vm 영역이 문맵으로 분할되는 방식에 기인하지만 다시 한 번 내 깊이에서 발생한다는 것입니다. 물론 스택 쿠키 검사및 null 페이지를 어떤 식으로든 매핑할 수 없음을 포함하여 여러 가지 이유로 인해 이 특정 한 악용 방법은 쓸모없는 것처럼 보입니다. 이 동작을 활용하는 일반적인 방법을 생각해 볼 수는 없지만 응용 프로그램이 공유 메모리가 포함된 영역에 프로세스 메모리 잠금을 적용했을 수 있습니다. 이 문제가 발생하면 munmap() 호출은 이러한 잠금을 무시하고 필요한 경우 해당 잠금을 제거합니다. __libc_free 손 은 IS_MMAPPED 비트가 munmap_chunk로 오른쪽으로 설정되어 있는 청크 위에 손을 놓고,이 경우 _int_free가 호출되지 않습니다. munmap_chunk (아래 약어 코드)에는 두 개의 무결성 검사, 일부 부기 및 munmap에 대한 실제 호출만 포함됩니다. 문맵의 반환 값은 유효성이 검사되지 않습니다. 무결성 검사는 munmap에 전달된 매개 변수가 페이지 정렬되지만 그 이상은 없는지 확인합니다.

main_stack.c 샘플 프로그램은 이 동작을 보여 줍니다. 현재 스택 프레임이 포함된 페이지의 맵핑을 해제할 수 있게 되어 결국 매핑되지 않은 페이지에 액세스하는 munmap의 ret 명령, 스택을 확장하는 커널 및 0으로 돌아가는 함수로 이어집니다. 청크의 절대 주소와 대상의 절대 주소입니다. munmap은 부분 매핑 해제를 지원하므로 필요한 경우 매핑의 한 페이지를 칠 수도 있습니다. munmap 함수는 mmap 함수에 의해 이전에 파일에 매핑된 메모리 영역의 일부 또는 전부의 매핑을 종료하는 데 사용됩니다. 위의 구현은 최소한의 예일 뿐이므로 오류를 제대로 확인하지 못합니다. ptmalloc이 mmapped 청크를 사용할 때 정렬 요구 사항을 처리하는 방법을 주의하는 것이 중요합니다. mmap은 페이지 정렬 영역을 반환하도록 보장되지만 사용자는 memalign 및 친구와 glibc에서 더 큰 정렬을 요청할 수 있습니다. 이 경우 _int_malloc을 통해 최악의 경우 패딩이 있는 할당을 가져와 요청된 크기의 청크를 필요한 정렬 경계에서 조각하고 사용자에게 반환할 수 있습니다. 이는 할당의 시작과 끝에 바이트가 낭비됨을 의미할 수 있으므로 선행 및 후행 공간은 무료로 반환됩니다.

그러나 _int_malloc이 mmapped 청크로 반환되면 mmapped 영역에 정렬된 청크의 오프셋이 헤더의 prev_size 필드에 저장됩니다. 이렇게 하면 청크에서 호출할 때 매핑된 영역의 시작을 자유롭게 찾을 수 있으며(아래 참조) 부분적으로 매핑을 해제할 수 없는 플랫폼(추측만)에 대한 지원을 유지하고 비용이 많이 드는 munmap 호출을 피할 수 있습니다.