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

This commit is contained in:
Jolan Rathelot 2024-11-20 11:53:23 +01:00
parent 80307195d4
commit 8ee8018212
4 changed files with 140 additions and 45 deletions

View File

@ -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:

View File

@ -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 <linux/rcupdate.h>
+#include <linux/path.h>
+
+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(&current_time);
+ u64 age_ms = (timespec64_to_ns(&current_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(&current_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

View File

@ -13,42 +13,75 @@
#include <linux/rcupdate.h>
#include <linux/path.h>
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(&current_time);
u64 age_ms = (timespec64_to_ns(&current_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(&current_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);
}

View File

@ -3,6 +3,7 @@
//
#include <linux/kernel.h>
#include <linux/limits.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <unistd.h>
@ -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);
}