commit 80307195d4090e03584b53e70a24247b844f186a Author: Jolan Rathelot Date: Tue Nov 19 17:24:09 2024 +0100 Inital commit: Simple POC syscall working and displaying in dmesg with tester tool diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8aa5cad --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +obj +ps_tester \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c515500 --- /dev/null +++ b/Makefile @@ -0,0 +1,53 @@ +KDIR ?= /lib/modules/$(shell uname -r)/build +SRC = src/process-and-memory.c +TESTER_SRC = src/tester/main.c +KERNEL_OUT ?= $(KDIR)/System.map $(KDIR)/arch/x86/boot/bzImage $(KDIR)/.config + +# Folders +SRC_DIR = src +OUTS = obj + +SRC = tester/main.c +SRC_PLUS_PATH = $(addprefix $(SRC_DIR)/, $(SRC)) +OUT = $(subst $(SRC_DIR)/, $(OUTS)/, $(patsubst %.c, %.o, $(SRC_PLUS_PATH))) + +NAME = ps_tester + +$(NAME): $(OUT) src/tester/main.c + @gcc $(OUT) -o $(NAME) -Wall -Wextra -Werror + +$(OUT): $(OUTS)/%.o : $(SRC_DIR)/%.c + @echo "Compiling $(basename $(notdir $*.o))" + @mkdir -p $(@D) + @gcc -Wall -Werror -Wextra -g -c $< -o $@ + +clean: + @echo "Cleaning object files" + @rm -rf obj + +fclean: clean + @echo "Cleaning binary" + @rm -rf ps_tester + +re: fclean + @$(MAKE) -C $$PWD + +patch_kernel: + +compile_kernel: patch_kernel + $(MAKE) -C $(KDIR) LLVM=1 -j 6 + +mount_boot: + mount /dev/vda1 + +install_kernel: mount_boot compile_kernel + $(MAKE) -C $(KDIR) LLVM=1 modules_install + cp -iv $(KDIR)/System.map /boot/System.map-6.12.0-modded + cp -iv $(KDIR)/arch/x86/boot/bzImage /boot/vmlinuz-6.12.0-jrathelo-modded + cp -iv $(KDIR)/.config /boot/config-6.12.0-modded + grub-mkconfig -o /boot/grub/grub.cfg + +install: install_kernel + reboot + +.PHONY: install compile_kernel install_kernel patch_kernel mount_boot diff --git a/patch.diff b/patch.diff new file mode 100644 index 0000000..cca4621 --- /dev/null +++ b/patch.diff @@ -0,0 +1,143 @@ +diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl +index 7093ee21c..b0d25489c 100644 +--- a/arch/x86/entry/syscalls/syscall_64.tbl ++++ b/arch/x86/entry/syscalls/syscall_64.tbl +@@ -386,6 +386,7 @@ + 460 common lsm_set_self_attr sys_lsm_set_self_attr + 461 common lsm_list_modules sys_lsm_list_modules + 462 common mseal sys_mseal ++463 common get_pid_info sys_get_pid_info + + # + # Due to a historical design error, certain syscalls are numbered differently +diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h +index 575810492..d68ac5243 100644 +--- a/include/linux/syscalls.h ++++ b/include/linux/syscalls.h +@@ -1197,6 +1197,9 @@ asmlinkage long sys_ni_syscall(void); + + asmlinkage long sys_ni_posix_timers(void); + ++/* CONFIG GET PID INFO */ ++asmlinkage long sys_get_pid_info(int pid); ++ + /* + * Kernel code should not call syscalls (i.e., sys_xyzyyz()) directly. + * Instead, use one of the functions which work equivalently, such as +diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h +index 5bf6148ca..52599890a 100644 +--- a/include/uapi/asm-generic/unistd.h ++++ b/include/uapi/asm-generic/unistd.h +@@ -841,8 +841,11 @@ __SYSCALL(__NR_lsm_list_modules, sys_lsm_list_modules) + #define __NR_mseal 462 + __SYSCALL(__NR_mseal, sys_mseal) + ++#define __NR_get_pid_info 463 ++__SYSCALL(__NR_get_pid_info, sys_get_pid_info) ++ + #undef __NR_syscalls +-#define __NR_syscalls 463 ++#define __NR_syscalls 464 + + /* + * 32 bit systems traditionally used different +@@ -866,7 +869,7 @@ __SYSCALL(__NR_mseal, sys_mseal) + #define __NR_newfstatat __NR3264_fstatat + #define __NR_fstat __NR3264_fstat + #endif +-#define __NR_mmap __NR3264_mmap ++#define __NR_mmap __NR3264_mmapmseal + #define __NR_fadvise64 __NR3264_fadvise64 + #ifdef __NR3264_stat + #define __NR_stat __NR3264_stat +diff --git a/kernel/Makefile b/kernel/Makefile +index 87866b037..15b5167fc 100644 +--- a/kernel/Makefile ++++ b/kernel/Makefile +@@ -50,6 +50,7 @@ obj-y += rcu/ + obj-y += livepatch/ + obj-y += dma/ + obj-y += entry/ ++obj-y += get_pid_info/ + obj-$(CONFIG_MODULES) += module/ + + obj-$(CONFIG_KCMP) += kcmp.o +diff --git a/kernel/get_pid_info/Makefile b/kernel/get_pid_info/Makefile +new file mode 100644 +index 000000000..2139af568 +--- /dev/null ++++ b/kernel/get_pid_info/Makefile +@@ -0,0 +1,3 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++obj-y += get_pid_info.o +diff --git a/kernel/get_pid_info/get_pid_info.c b/kernel/get_pid_info/get_pid_info.c +new file mode 100644 +index 000000000..9acc550b2 +--- /dev/null ++++ b/kernel/get_pid_info/get_pid_info.c +@@ -0,0 +1,54 @@ ++// ++// Created by jrathelo on 11/18/24. ++// ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++SYSCALL_DEFINE1(get_pid_info, int, pid) { ++ struct task_struct *task; ++ char buf[PATH_MAX]; ++ char *path; ++ struct timespec64 current_time; ++ ++ rcu_read_lock(); ++ task = pid_task(find_vpid(pid), PIDTYPE_PID); ++ if (task) { ++ pr_info("Process ID: %d\n", pid); ++ pr_info("Process Name: %s\n", task->comm); ++ pr_info("Process State: %x\n", task->__state); ++ pr_info("Stack address: %p\n", task->stack); ++ ktime_get_boottime_ts64(¤t_time); ++ u64 age_ms = (timespec64_to_ns(¤t_time) - task->start_time) / 1000000; ++ pr_info("Process Age: %llu ms\n", age_ms); ++ pr_info("Children list address: %llu\n", task->children); ++ pr_info("Parent PID: %d\n", task->parent->pid); ++ if (!task->fs) { ++ pr_info("No filesystem context found\n"); ++ rcu_read_unlock(); ++ return 0; ++ } ++ path = d_path(&task->fs->root, buf, PATH_MAX); ++ if (IS_ERR(path)) { ++ pr_info("Failed to resolve root path\n"); ++ } else { ++ pr_info("Root Path: %s\n", path); ++ } ++ path = d_path(&task->fs->pwd, buf, PATH_MAX); ++ if (IS_ERR(path)) { ++ pr_info("Failed to resolve PWD\n"); ++ } else { ++ pr_info("Current Working Directory: %s\n", path); ++ } ++ } ++ rcu_read_unlock(); ++ return 0; ++} +diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c +index c00a86931..95daa731d 100644 +--- a/kernel/sys_ni.c ++++ b/kernel/sys_ni.c +@@ -392,3 +392,5 @@ COND_SYSCALL(setuid16); + COND_SYSCALL(rseq); + + COND_SYSCALL(uretprobe); ++ ++COND_SYSCALL(get_pid_info); diff --git a/src/get_pid_info.c b/src/get_pid_info.c new file mode 100644 index 0000000..9acc550 --- /dev/null +++ b/src/get_pid_info.c @@ -0,0 +1,54 @@ +// +// Created by jrathelo on 11/18/24. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +SYSCALL_DEFINE1(get_pid_info, int, pid) { + struct task_struct *task; + char buf[PATH_MAX]; + char *path; + struct timespec64 current_time; + + rcu_read_lock(); + task = pid_task(find_vpid(pid), PIDTYPE_PID); + if (task) { + pr_info("Process ID: %d\n", pid); + pr_info("Process Name: %s\n", task->comm); + pr_info("Process State: %x\n", task->__state); + pr_info("Stack address: %p\n", task->stack); + ktime_get_boottime_ts64(¤t_time); + u64 age_ms = (timespec64_to_ns(¤t_time) - task->start_time) / 1000000; + pr_info("Process Age: %llu ms\n", age_ms); + pr_info("Children list address: %llu\n", task->children); + pr_info("Parent PID: %d\n", task->parent->pid); + if (!task->fs) { + pr_info("No filesystem context found\n"); + rcu_read_unlock(); + return 0; + } + path = d_path(&task->fs->root, buf, PATH_MAX); + if (IS_ERR(path)) { + pr_info("Failed to resolve root path\n"); + } else { + pr_info("Root Path: %s\n", path); + } + path = d_path(&task->fs->pwd, buf, PATH_MAX); + if (IS_ERR(path)) { + pr_info("Failed to resolve PWD\n"); + } else { + pr_info("Current Working Directory: %s\n", path); + } + } + rcu_read_unlock(); + return 0; +} diff --git a/src/tester/main.c b/src/tester/main.c new file mode 100644 index 0000000..7e750f8 --- /dev/null +++ b/src/tester/main.c @@ -0,0 +1,26 @@ +// +// Created by jrathelo on 11/18/24. +// + +#include +#include +#include +#include +#include +#include +#include + +#define __NR_get_pid_info 463 + +long get_pid_info_syscall(int pid) { + return syscall(__NR_get_pid_info, pid); +} + +int main(int argc, char *argv[]) { + if (argc < 2) { + printf("Usage: %s [pid]\n", argv[0]); + return -1; + } + return get_pid_info_syscall(atoi(argv[1])); +} +