시스템 호출 테이블 ( sys_call_table
)이 정적 크기 배열 이므로 불가능합니다 . 그리고 그 크기는 컴파일 타임에 등록 된 syscall 수에 의해 결정됩니다. 이것은 다른 공간이 없다는 것을 의미합니다.
정의 된 arch/x86/kernel/syscall_64.c
파일의 x86 아키텍처에 대한 구현을 확인할 수 있습니다 sys_call_table
. 크기는 정확히 __NR_syscall_max+1
입니다. __NR_syscall_max
로 정의 arch/x86/kernel/asm-offsets_64.c
됩니다 sizeof(syscalls) - 1
(마지막 syscall 수). 여기서 syscall
모든 syscall이있는 테이블입니다.
하나의 가능한 해결책은 sys_setaltroot
메모리에 더 많은 공간이 필요하지 않기 때문에 기존의 일부 syscall 번호 (예 : 아키텍처에 하나가 있으면 더 이상 사용되지 않는 것)를 재사용하는 것입니다. 일부 아키텍처에는 syscall 테이블 (예 : x86의 64 비트 버전)에 구멍이있을 수 있으므로이 아키텍처도 사용할 수 있습니다.
새로운 syscall을 개발 중이고 실험하는 동안 재부팅하지 않으려는 경우이 기술을 사용할 수 있습니다. 새 시스템 호출을 정의하고 syscall 테이블에서 기존 항목을 찾은 다음 모듈에서이를 교체해야합니다.
커널이 sys_call_table
2.6 버전으로 모듈로 내보내지지 않기 때문에 커널 모듈에서이 작업을 수행하는 것은 쉬운 일이 아닙니다 (이 기호를 내 보낸 마지막 커널 버전은 2.5.41
).
이 문제를 해결하는 한 가지 방법은 커널을 변경하여 sys_call_table
심볼을 모듈 로 내보내는 것 입니다. 이렇게하려면 다음 두 줄을 추가 해야 합니다 kernel/kallsyms.c
( 생산 시스템에서는이 작업을 수행하지 마십시오 ).
extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);
다른 기술은 syscall 테이블을 동적으로 찾는 것입니다. 알려진 시스템 호출 함수에 대한 포인터와 각 단어를 비교하여 커널 메모리를 반복합니다. 테이블에서이 알고있는 syscall의 오프셋을 알고 있으므로 테이블 시작 주소를 계산할 수 있습니다.