1. 서론
- 리눅스 운영체제는 모놀리식 커널 구조 기반에서 동작하며, 커널 기능 확장을 위해 커널 모듈(Kernel Module) 구조 제공함
- 커널 모듈은 사용자 공간의 응용 프로그램과 달리 커널 공간에서 직접 실행되며, 시스템 자원 및 하드웨어에 대한 직접 접근 가능함
- 잘못된 커널 모듈 작성 시 시스템 전체의 안정성과 보안성 저해 가능성이 존재함
- 이에 따라 커널 모듈의 구조적 특징과 메모리 접근 제약 요소에 대한 이해 필요함
2. 리눅스 커널 모듈의 기본 구조
2.1 커널 모듈 개념
- 커널 실행 중 동적으로 로딩(loading) 및 언로딩(unloading) 가능한 코드 단위
insmod
,rmmod
,modprobe
명령어 등을 통해 로딩 및 제거 수행- 커널과 커널 모듈 간 인터페이스는
EXPORT_SYMBOL
,include/linux/module.h
헤더 기반으로 정의됨
2.2 기본 구성 요소
헤더 포함부
#include <linux/module.h>
: 모듈 매크로 및 인터페이스 정의#include <linux/kernel.h>
: printk 로그 함수 등 정의#include <linux/init.h>
: 모듈 초기화/종료 선언 매크로 포함
모듈 초기화 함수 (
init
)- 모듈 로드시 실행됨
module_init()
매크로로 등록- 예시:
static int __init my_module_init(void) { ... }
모듈 종료 함수 (
exit
)- 모듈 제거시 실행됨
module_exit()
매크로로 등록- 예시:
static void __exit my_module_exit(void) { ... }
메타 정보 정의부
MODULE_LICENSE("GPL")
,MODULE_AUTHOR
,MODULE_DESCRIPTION
등으로 모듈 정보 선언
2.3 Makefile 구성
obj-m += my_module.o
형태로 모듈 대상 명시make -C /lib/modules/$(uname -r)/build M=$(PWD) modules
형태로 빌드 수행
3. 커널 모듈과 메모리 접근 구조
3.1 커널과 사용자 공간 메모리 분리
- 리눅스는 가상 메모리 구조를 기반으로 사용자 공간(user space)과 커널 공간(kernel space)을 명확히 분리함
- 사용자 공간 프로세스는 직접적으로 커널 공간 접근 불가능함
- 커널 모듈은 커널 공간에서 실행되므로 사용자 공간 메모리에 대한 직접 접근 시 엄격한 제한 적용됨
3.2 주요 메모리 접근 함수 및 보호 매커니즘
구분 | 내용 |
---|---|
copy_from_user() |
사용자 공간 데이터를 커널 공간으로 복사 |
copy_to_user() |
커널 공간 데이터를 사용자 공간으로 복사 |
get_user() / put_user() |
단일 값 읽기/쓰기 지원 함수 |
kmalloc() / kfree() |
커널 힙 영역에서 동적 메모리 할당 |
vmalloc() |
큰 메모리 공간 할당 시 사용, 물리적 연속성 없음 |
__user |
사용자 포인터를 나타내는 타입 선언 키워드 |
페이지 테이블 보호 | 사용자와 커널 주소 공간에 대한 접근 제어 역할 수행 |
CONFIG_STRICT_KERNEL_RWX |
커널 코드 영역을 읽기 전용으로 설정하여 악성 수정 방지 |
3.3 접근 제한 정책 및 보호 기법
- Memory Protection Unit(MPU) 기반 보호 구조
→ 사용자 영역에서 커널 영역 접근 시 page fault 발생 유도 - KASLR (Kernel Address Space Layout Randomization)
→ 커널 메모리 주소를 무작위화하여 공격자 주소 예측 회피 - smep/smap (Supervisor Mode Execution/Access Prevention)
→ 커널이 사용자 공간 메모리 실행/접근을 차단 - SELinux / AppArmor 정책 연계
→ 모듈 접근 권한 제한 및 보안 감사 수행 가능
4. 커널 모듈 개발 시 주요 유의사항
4.1 메모리 안정성 확보
- 포인터 유효성 검사 필수
- 사용자 포인터 접근 시
copy_to_user
/copy_from_user
사용 권장 - 메모리 할당 후
NULL
반환 체크 필요 - 할당 후 반드시 해제 수행 → memory leak 방지
4.2 커널 패닉 방지
- 잘못된 포인터 역참조나 null dereference는 커널 패닉 발생 원인
- 커널 로그 분석을 위한
printk
적절 활용 필요 - 커널 panic 방지 위한
BUG_ON
,WARN_ON
매크로 활용 가능
4.3 코드 서명 및 보안 이슈
- 최신 커널에서는 커널 모듈 서명 필요 (
CONFIG_MODULE_SIG=y
) - 공식 키로 서명되지 않은 모듈은 로딩 불가 (Secure Boot 환경)
- 서명 인증 우회 시 보안 위협 가능성이 존재하므로 신뢰 경로 유지 필요
5. 결론
- 리눅스 커널 모듈은 고성능 시스템 확장과 하드웨어 제어 기능 구현에 유용한 도구임
- 그러나 시스템 자원에 대한 직접 접근 가능성으로 인해 메모리 안정성과 보안 문제가 상존함
- 커널 공간과 사용자 공간의 명확한 메모리 분리 이해와 더불어 접근 함수 및 보호 기법의 숙지가 필수임
- 보안 중심의 개발 습관과 커널 버전 정책에 맞는 모듈 설계가 신뢰성 높은 시스템 구축의 핵심임
'IT Study > SW 개발 및 프로그래밍' 카테고리의 다른 글
💻 동적 타입 언어에서의 타입 안정성 확보 전략(Type Hint, MyPy 등) (1) | 2025.04.20 |
---|---|
💻 CLI vs GUI 아키텍처 설계 방식 비교와 UX 고려 요소 (1) | 2025.04.19 |
💻 메모리 관리 기법(Marking, Sweeping, Compaction 등)의 비교 이해 (1) | 2025.04.17 |
💻 인터프리터 언어의 메모리 구조(Stack, Heap) 이해 (0) | 2025.04.16 |
💻 가비지 컬렉션(Garbage Collection) 방식과 메모리 누수 추적 (1) | 2025.04.15 |