From 8ee8018212db5de8d885e8b112ae24b2f9c6db0b Mon Sep 17 00:00:00 2001 From: Jolan Rathelot Date: Wed, 20 Nov 2024 11:53:23 +0100 Subject: [PATCH] Copy kernel data to user, does everything but the return array of child pids, have the method to get them but currently brainstorming how to send to user since its variable --- Makefile | 2 +- patch.diff | 79 ++++++++++++++++++++++++++++++++-------------- src/get_pid_info.c | 69 +++++++++++++++++++++++++++++----------- src/tester/main.c | 35 ++++++++++++++++++-- 4 files changed, 140 insertions(+), 45 deletions(-) diff --git a/Makefile b/Makefile index c515500..8469930 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ re: fclean patch_kernel: -compile_kernel: patch_kernel +compile_kernel: #patch_kernel $(MAKE) -C $(KDIR) LLVM=1 -j 6 mount_boot: diff --git a/patch.diff b/patch.diff index cca4621..20f1c0f 100644 --- a/patch.diff +++ b/patch.diff @@ -11,15 +11,26 @@ index 7093ee21c..b0d25489c 100644 # # 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 +index 575810492..1efb297e1 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h -@@ -1197,6 +1197,9 @@ asmlinkage long sys_ni_syscall(void); +@@ -1197,6 +1197,20 @@ 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); ++struct pid_info { ++ int pid; ++ u32 state; ++ const void *stack; ++ u64 age; ++ // int * children; ++ int parent_pid; ++ char root_path[PATH_MAX]; ++ char working_directory[PATH_MAX]; ++}; ++ ++asmlinkage long sys_get_pid_info(struct pid_info * p_info_struct, int pid); + /* * Kernel code should not call syscalls (i.e., sys_xyzyyz()) directly. @@ -73,10 +84,10 @@ index 000000000..2139af568 +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 +index 000000000..21ff5f699 --- /dev/null +++ b/kernel/get_pid_info/get_pid_info.c -@@ -0,0 +1,54 @@ +@@ -0,0 +1,76 @@ +// +// Created by jrathelo on 11/18/24. +// @@ -92,45 +103,67 @@ index 000000000..9acc550b2 +#include +#include + -+SYSCALL_DEFINE1(get_pid_info, int, pid) { ++static long __sys_get_pid_info(struct pid_info __user * p_info_struct, int pid) { + struct task_struct *task; -+ char buf[PATH_MAX]; -+ char *path; ++ char * path; + struct timespec64 current_time; + ++ struct pid_info *data = (struct pid_info *) kzalloc(sizeof(struct pid_info), GFP_KERNEL); ++ if (data == NULL) { ++ return -ENOMEM; ++ } ++ ++ int error = copy_from_user(data, p_info_struct, sizeof(struct pid_info)); ++ if (error) { ++ kfree(data); ++ return -EFAULT; ++ } ++ + 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); ++ data->pid = pid; ++ data->state = task->__state; ++ data->stack = 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); ++ data->age = (timespec64_to_ns(¤t_time) - task->start_time); ++ if (task->parent) { ++ data->parent_pid = task->parent->pid; ++ } else { ++ data->parent_pid = 0; ++ } + if (!task->fs) { -+ pr_info("No filesystem context found\n"); ++ memset(data->root_path, 0, PATH_MAX); ++ memset(data->working_directory, 0, PATH_MAX); + rcu_read_unlock(); + return 0; + } -+ path = d_path(&task->fs->root, buf, PATH_MAX); ++ path = d_path(&task->fs->root, data->root_path, PATH_MAX); + if (IS_ERR(path)) { -+ pr_info("Failed to resolve root path\n"); ++ memset(data->root_path, 0, PATH_MAX); + } else { -+ pr_info("Root Path: %s\n", path); ++ memcpy(data->root_path, path, PATH_MAX); + } -+ path = d_path(&task->fs->pwd, buf, PATH_MAX); ++ path = d_path(&task->fs->pwd, data->working_directory, PATH_MAX); + if (IS_ERR(path)) { -+ pr_info("Failed to resolve PWD\n"); ++ memset(data->working_directory, 0, PATH_MAX); + } else { -+ pr_info("Current Working Directory: %s\n", path); ++ memcpy(data->working_directory, path, PATH_MAX); + } + } + rcu_read_unlock(); ++ error = copy_to_user(p_info_struct, data, sizeof(struct pid_info)); ++ if (error) { ++ kfree(data); ++ return -EFAULT; ++ } ++ kfree(data); + return 0; +} ++ ++SYSCALL_DEFINE2(get_pid_info, struct pid_info __user *, p_info_struct, int, pid) { ++ return __sys_get_pid_info(p_info_struct, pid); ++} diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index c00a86931..95daa731d 100644 --- a/kernel/sys_ni.c diff --git a/src/get_pid_info.c b/src/get_pid_info.c index 9acc550..7be1321 100644 --- a/src/get_pid_info.c +++ b/src/get_pid_info.c @@ -13,42 +13,75 @@ #include #include -SYSCALL_DEFINE1(get_pid_info, int, pid) { +struct pid_info { + int pid; + u32 state; + const void *stack; + u64 age; + // int * children; + int parent_pid; + char root_path[PATH_MAX]; + char working_directory[PATH_MAX]; +}; + +static long __sys_get_pid_info(struct pid_info __user * p_info_struct, int pid) { struct task_struct *task; - char buf[PATH_MAX]; - char *path; + char * path; struct timespec64 current_time; + struct pid_info *data = (struct pid_info *) kzalloc(sizeof(struct pid_info), GFP_KERNEL); + if (data == NULL) { + return -ENOMEM; + } + + int error = copy_from_user(data, p_info_struct, sizeof(struct pid_info)); + if (error) { + kfree(data); + return -EFAULT; + } + 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); + data->pid = pid; + data->state = task->__state; + data->stack = 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); + data->age = (timespec64_to_ns(¤t_time) - task->start_time); + if (task->parent) { + data->parent_pid = task->parent->pid; + } else { + data->parent_pid = 0; + } if (!task->fs) { - pr_info("No filesystem context found\n"); + memset(data->root_path, 0, PATH_MAX); + memset(data->working_directory, 0, PATH_MAX); rcu_read_unlock(); return 0; } - path = d_path(&task->fs->root, buf, PATH_MAX); + path = d_path(&task->fs->root, data->root_path, PATH_MAX); if (IS_ERR(path)) { - pr_info("Failed to resolve root path\n"); + memset(data->root_path, 0, PATH_MAX); } else { - pr_info("Root Path: %s\n", path); + memcpy(data->root_path, path, PATH_MAX); } - path = d_path(&task->fs->pwd, buf, PATH_MAX); + path = d_path(&task->fs->pwd, data->working_directory, PATH_MAX); if (IS_ERR(path)) { - pr_info("Failed to resolve PWD\n"); + memset(data->working_directory, 0, PATH_MAX); } else { - pr_info("Current Working Directory: %s\n", path); + memcpy(data->working_directory, path, PATH_MAX); } } rcu_read_unlock(); + error = copy_to_user(p_info_struct, data, sizeof(struct pid_info)); + if (error) { + kfree(data); + return -EFAULT; + } + kfree(data); return 0; } + +SYSCALL_DEFINE2(get_pid_info, struct pid_info __user *, p_info_struct, int, pid) { + return __sys_get_pid_info(p_info_struct, pid); +} diff --git a/src/tester/main.c b/src/tester/main.c index 7e750f8..ca9b671 100644 --- a/src/tester/main.c +++ b/src/tester/main.c @@ -3,6 +3,7 @@ // #include +#include #include #include #include @@ -12,8 +13,20 @@ #define __NR_get_pid_info 463 -long get_pid_info_syscall(int pid) { - return syscall(__NR_get_pid_info, pid); +struct pid_info { + int pid; + unsigned int state; + const void *stack; + unsigned long long age; + // int * children; + int parent_pid; + char root_path[PATH_MAX]; + char working_directory[PATH_MAX]; +}; + + +long get_pid_info(struct pid_info * ret, int pid) { + return syscall(__NR_get_pid_info, ret, pid); } int main(int argc, char *argv[]) { @@ -21,6 +34,22 @@ int main(int argc, char *argv[]) { printf("Usage: %s [pid]\n", argv[0]); return -1; } - return get_pid_info_syscall(atoi(argv[1])); + struct pid_info data; + + long ret = get_pid_info(&data, atoi(argv[1])); + if (ret) { + return ret; + } + if (data.pid == 0) { + return 1; + } + + printf("Pid: %d\n", data.pid); + printf("State; %d\n", data.state); + printf("Age : %lld ms\n", data.age / 1000000); + printf("Parent PID: %d\n", data.parent_pid); + printf("Root Path: %s\n", data.root_path); + printf("Current Working Directory: %s\n", data.working_directory); + }