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); + }