리눅스 시스템 콜 추가

sangjuneeeee·2024년 6월 3일
post-thumbnail

환경

  • Oracle VM VirtualBox
  • 기본 메모리: 8192MB
  • 프로세서: 6
  • 저장공간: 40GB
  • Ubuntu (64-bit) / 22.04.4
  • linux-6.5

개요

문제

Attack_on_POSIX프로그램은 5초마다 지정된 메시지 중 무작위로 출력하는 프로세스를 30초마다 생성하는 프로그램이다.

따라서
for_each_process를 이용해 모든 프로세스를 순회하고,
get_task_comm를 이용해 프로세스의 이름을 불러와 비교하여
"Attack_on_POSIX"와 일치하면 프로세스를 KILL하고 커널 로그에 "Clear"를
일치하는 프로세스가 없다면 "Safe now"를 출력하도록 한다.

공유 파일

Oracle VM VirtualBox의 공유폴더를 이용하여 파일을 공유 함

설정 > 공유 폴더 > 공유 추가 > 경로 선택 > 자동 마운트 > 확인

그 후 리눅스에서 아래의 명령어를 수행

%% on Linux %%

sudo mkdir -p /mnt/vmbox_share
sudo mount -t vboxsf vmbox_share[공유폴더의 이름] /mnt/vmbox_share

다운로드

https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/

  • ChangeLog: 변경 사항 목록
  • patch: 커널 업데이트
  • sha25sums: 무결성 검증 파일
  • linux: 리눅스 커널 소스 코드

.gz보다 .xz가 압축률이 더 좋기 때문에 linux-6.5.tar.xz 다운

wget https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.5.tar.xz

압축 해제

tar -xvf linux-6.5.tar.xz
  • -x: extract, 아카이브에서 파일을 추출
  • -v: verbose, 처리되는 파일 이름을 화면에 표시
  • -f: file, 나오는 파일 이름에서 아카이브를 읽기

과정

시스템 콜 코드

SYSCLL_DEFINE 매크로를 이용하면 더 간단하게 시스템 콜을 추가할 수 있다.

// linux-6.5/kernel/kill_attack_on_posix.c

#include <linux/sched/signal.h> // for_each_process가 포함된 라이브러리
#include <linux/sched.h> // get_task_comm가 포함된 라이브러리
#include <linux/string.h>
#include <linux/syscalls.h>

SYSCALL_DEFINE0(sys_kill_attack_on_posix) {
    struct task_struct* ps; 
    // task_struct: 프로세스의 상태 구조
    char ps_name[TASK_COMM_LEN];
    // TASK_COMM_LEN: 프로세스의 이름을 저장하기 위한 버퍼의 크기를 정의하는 매크로
    for_each_process(ps) {  // 시스템의 모든 프로세스를 순회
        get_task_comm(ps_name, ps); // 현재 프로세스의 이름을 가져옴
        if (strncmp(ps_name, "Attack_on_POSIX", TASK_COMM_LEN) == 0) { // 프로세스 이름을 "Attack_on_POSIX" 비교
            send_sig(SIGKILL, ps, 0); // 일치하는 경우, 프로세스 종료
            printk("Clear\n"); // 커널에 'Clear' 출력
            return 0;
        }
    }
    printk("Safe now\n"); // "Attack_on_POSIX" 프로세스가 없을 경우 커널에 'Safe now' 출력
    return 0;
}

SYSCALL_DEFINE 매크로는 시스템 콜을 정의하고 필요한 초기화 작업을 자동으로 처리

kernel/Makefile 추가

linux-6.5/kernel/Makefile
obj-ykill_attack_on_posix.o추가

컴파일 과정에서 새로운 시스템 콜이 포함되도록 제어

시스템 콜 테이블 등록

linux-6.5/arch/x86/entry/syscalls/syscall_64.tbl

452번 째에 시스템 콜 추가

시스템 콜 테이블은 시스템 콜 번호와 함수 간의 매핑을 관리

헤더 파일에 추가

linux-6.5/include/linux/syscalls.h
asmlinkage long kill_attack_on_posix(void); 추가

맨 밑에 추가하였다.

헤더 파일은 함수 프로토타입을 정의하여 컴파일러가 올바르게 인식하도록

asmlinkage 키워드는 시스템 콜 함수 선언에서 호출 규약을 지정하여, 인자가 커널 공간(더 자세히는 커널 스택)을 통해 전달되도록 함

커널 버전 명 변경

linux-6.5/에서 Makefile수정

컴파일 및 빌드

sudo su
make defconfig

make defconfig 명령어로 모든 세팅값을 defaults로 하여 컴파일 간에 생기는 오류를 최소화 하였다.

grep -c processor /proc/cpuinfo명령어로 코어 수가 6임을 확인

make 명령어로 컴파일 한다.

apt install build-essential libncurses5 libncurses5-dev bin86 libssl-dev bison flex libelf-dev
make -j6
make modules
make modules_install 
make install
reboot

make modules_install 명령어를 실행 시
permission denied 문제가 나타나므로 sudo su 명령어로 root권한을 주었다.

make modules 명령어가 성공적으로 수행 됐음을 확인

결과

버전 명

uname -r명령어로 버전명을 확인할 수 있다.
Makefile EXTRAVERSION에 추가했던 -parksangjun도 확인이 가능하다.

시스템 콜 실행 코드

// test.c

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>

// 시스템 콜 테이블 번호
#define KILL_ATTACK_ON_POSIX 452

int main() {
    long status;

    // 시스템 콜 호출
    status = syscall(KILL_ATTACK_ON_POSIX);

    return 0;
}

테스트 코드 컴파일

gcc test.c -o test

실행 및 결과

dmesg명령어로 커널 로그를 확인할 수 있다.


발생했던 에러 및 해결

인증서 문제

  • error

리눅스 파일 최상위 폴더에서

make defconfig
vi .config

초기에는 KEYS 값이 설정 되어있어 오류가 발생해 make defconfig 명령어로 .config파일을 기본값으로설정해주어 오류를 해결하였다.

저장공간 문제

  • error
ld: drivers/net/wireless/ath/ath6kl/ath6kl/_core.o: final close failed: No space left on device

컴파일 중 저장공간 오류 발생하였다.

새로 충분한 공간의 디스크 이미지를 생성하여 해결하였다.

undefined reference to 문제

  • error

컴파일 시, 헤더 파일에 선언은 되어있으나, 소스 파일에 정의가 안되어 있다는 의미

SYSCALL_DEFINE0(kill_attack_on_posix) {
	return kill_attack_on_posix();
}

코드를 추가하여 오류를 해결하였으며,

최종적으로는

이와 같이 코드를 수정하여 작성하였다.

profile
지식 쌓아두기 블로그

0개의 댓글