Krafton Jungle/5. PintOS
[PintOS 2주차] Day 7
munsik22
2025. 5. 21. 16:45
create-bad-ptr 해결하기
/* create-bad-ptr.c */
#include "tests/lib.h"
#include "tests/main.h"
void test_main (void) {
msg ("create(0x20101234): %d", create ((char *) 0x20101234, 0));
}
이 코드는 create 시스템 콜에 bad pointer를 넘겨서, exit(-1)로 프로세스를 종료시키게 해야 한다. 여기서 0x20101234가 왜 'bad pointer'일까?
기존에 구현했던 create()는 다음과 같다.
bool create (const char *file, unsigned initial_size) {
if (!is_user_vaddr(file)) exit(-1);
else printf("you good\n"); // for debugging
if (file == NULL) exit(-1);
return filesys_create(file, initial_size);
}
처음에는 메모리 주소가 커널 영역만 넘어서지 않으면 PF가 발생하지 않을 것이라고 생각해서, 입력받은 주소가 단순히 유저 메모리 영역 안에 있는지만 확인했다. 0x20101234는 USER_STACK(0x47480000)보다 작으므로 유저 영역 안의 주소다.

그럼에도 불구하고 이것은 bad pointer고, 여전히 PF가 발생한다. 이는 단순히 "USER_STACK보다 작은지"를 봐야하는 것이 아니라, "실제로 유효한 페이지 매핑이 있는지"를 판단해야 하기 때문이다.
PML4Page Map Level 4는 x86-64 아키텍처에서 가상주소를 (물리주소로) 변환하기 위한 최상위 페이지 테이블이다.

위 그림에서 보이듯이, 가상 주소는 Sign Extend를 제외한 48비트 기준 다음처럼 나뉜다.
| PML4 | PDPT | PD | PT | Offset |
| 9 bits | 9 bits | 9 bits | 9 bits | 12 bits |
pml4_get_page(pml4, vaddr)은 가상 주소 vaddr이 매핑되어 있는지 확인하는 함수로, 물리 주소로 잘 매핑이 되었으면 유효한 (void *) 값을, 아니면 NULL을 리턴한다. 이 함수를 이용해서 create()를 다음과 같이 수정해야 한다.
bool create (const char *file, unsigned initial_size) {
if (!is_user_vaddr(file)) exit(-1);
if (!pml4_get_page(thread_current()->pml4, file)) exit(-1); // ← 추가
if (file == NULL) exit(-1);
return filesys_create(file, initial_size);
}
