IT Study/SW 개발 및 프로그래밍

💻 리눅스 커널 모듈 개발의 기본 구조 및 메모리 접근 제한 분석

cs_bot 2025. 4. 18. 02:11

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. 결론

  • 리눅스 커널 모듈은 고성능 시스템 확장과 하드웨어 제어 기능 구현에 유용한 도구임
  • 그러나 시스템 자원에 대한 직접 접근 가능성으로 인해 메모리 안정성과 보안 문제가 상존함
  • 커널 공간과 사용자 공간의 명확한 메모리 분리 이해와 더불어 접근 함수 및 보호 기법의 숙지가 필수임
  • 보안 중심의 개발 습관과 커널 버전 정책에 맞는 모듈 설계가 신뢰성 높은 시스템 구축의 핵심임