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:
parent
80307195d4
commit
8ee8018212
2
Makefile
2
Makefile
@ -34,7 +34,7 @@ re: fclean
|
|||||||
|
|
||||||
patch_kernel:
|
patch_kernel:
|
||||||
|
|
||||||
compile_kernel: patch_kernel
|
compile_kernel: #patch_kernel
|
||||||
$(MAKE) -C $(KDIR) LLVM=1 -j 6
|
$(MAKE) -C $(KDIR) LLVM=1 -j 6
|
||||||
|
|
||||||
mount_boot:
|
mount_boot:
|
||||||
|
79
patch.diff
79
patch.diff
@ -11,15 +11,26 @@ index 7093ee21c..b0d25489c 100644
|
|||||||
#
|
#
|
||||||
# Due to a historical design error, certain syscalls are numbered differently
|
# Due to a historical design error, certain syscalls are numbered differently
|
||||||
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
|
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
|
--- a/include/linux/syscalls.h
|
||||||
+++ b/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);
|
asmlinkage long sys_ni_posix_timers(void);
|
||||||
|
|
||||||
+/* CONFIG GET PID INFO */
|
+/* 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.
|
* Kernel code should not call syscalls (i.e., sys_xyzyyz()) directly.
|
||||||
@ -73,10 +84,10 @@ index 000000000..2139af568
|
|||||||
+obj-y += get_pid_info.o
|
+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
|
diff --git a/kernel/get_pid_info/get_pid_info.c b/kernel/get_pid_info/get_pid_info.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 000000000..9acc550b2
|
index 000000000..21ff5f699
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/kernel/get_pid_info/get_pid_info.c
|
+++ b/kernel/get_pid_info/get_pid_info.c
|
||||||
@@ -0,0 +1,54 @@
|
@@ -0,0 +1,76 @@
|
||||||
+//
|
+//
|
||||||
+// Created by jrathelo on 11/18/24.
|
+// Created by jrathelo on 11/18/24.
|
||||||
+//
|
+//
|
||||||
@ -92,45 +103,67 @@ index 000000000..9acc550b2
|
|||||||
+#include <linux/rcupdate.h>
|
+#include <linux/rcupdate.h>
|
||||||
+#include <linux/path.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;
|
+ struct task_struct *task;
|
||||||
+ char buf[PATH_MAX];
|
+ char * path;
|
||||||
+ char *path;
|
|
||||||
+ struct timespec64 current_time;
|
+ 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();
|
+ rcu_read_lock();
|
||||||
+ task = pid_task(find_vpid(pid), PIDTYPE_PID);
|
+ task = pid_task(find_vpid(pid), PIDTYPE_PID);
|
||||||
+ if (task) {
|
+ if (task) {
|
||||||
+ pr_info("Process ID: %d\n", pid);
|
+ data->pid = pid;
|
||||||
+ pr_info("Process Name: %s\n", task->comm);
|
+ data->state = task->__state;
|
||||||
+ pr_info("Process State: %x\n", task->__state);
|
+ data->stack = task->stack;
|
||||||
+ pr_info("Stack address: %p\n", task->stack);
|
|
||||||
+ ktime_get_boottime_ts64(¤t_time);
|
+ ktime_get_boottime_ts64(¤t_time);
|
||||||
+ u64 age_ms = (timespec64_to_ns(¤t_time) - task->start_time) / 1000000;
|
+ data->age = (timespec64_to_ns(¤t_time) - task->start_time);
|
||||||
+ pr_info("Process Age: %llu ms\n", age_ms);
|
+ if (task->parent) {
|
||||||
+ pr_info("Children list address: %llu\n", task->children);
|
+ data->parent_pid = task->parent->pid;
|
||||||
+ pr_info("Parent PID: %d\n", task->parent->pid);
|
+ } else {
|
||||||
|
+ data->parent_pid = 0;
|
||||||
|
+ }
|
||||||
+ if (!task->fs) {
|
+ 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();
|
+ rcu_read_unlock();
|
||||||
+ return 0;
|
+ 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)) {
|
+ if (IS_ERR(path)) {
|
||||||
+ pr_info("Failed to resolve root path\n");
|
+ memset(data->root_path, 0, PATH_MAX);
|
||||||
+ } else {
|
+ } 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)) {
|
+ if (IS_ERR(path)) {
|
||||||
+ pr_info("Failed to resolve PWD\n");
|
+ memset(data->working_directory, 0, PATH_MAX);
|
||||||
+ } else {
|
+ } else {
|
||||||
+ pr_info("Current Working Directory: %s\n", path);
|
+ memcpy(data->working_directory, path, PATH_MAX);
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ rcu_read_unlock();
|
+ 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;
|
+ 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
|
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
|
||||||
index c00a86931..95daa731d 100644
|
index c00a86931..95daa731d 100644
|
||||||
--- a/kernel/sys_ni.c
|
--- a/kernel/sys_ni.c
|
||||||
|
@ -13,42 +13,75 @@
|
|||||||
#include <linux/rcupdate.h>
|
#include <linux/rcupdate.h>
|
||||||
#include <linux/path.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;
|
struct task_struct *task;
|
||||||
char buf[PATH_MAX];
|
char * path;
|
||||||
char *path;
|
|
||||||
struct timespec64 current_time;
|
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();
|
rcu_read_lock();
|
||||||
task = pid_task(find_vpid(pid), PIDTYPE_PID);
|
task = pid_task(find_vpid(pid), PIDTYPE_PID);
|
||||||
if (task) {
|
if (task) {
|
||||||
pr_info("Process ID: %d\n", pid);
|
data->pid = pid;
|
||||||
pr_info("Process Name: %s\n", task->comm);
|
data->state = task->__state;
|
||||||
pr_info("Process State: %x\n", task->__state);
|
data->stack = task->stack;
|
||||||
pr_info("Stack address: %p\n", task->stack);
|
|
||||||
ktime_get_boottime_ts64(¤t_time);
|
ktime_get_boottime_ts64(¤t_time);
|
||||||
u64 age_ms = (timespec64_to_ns(¤t_time) - task->start_time) / 1000000;
|
data->age = (timespec64_to_ns(¤t_time) - task->start_time);
|
||||||
pr_info("Process Age: %llu ms\n", age_ms);
|
if (task->parent) {
|
||||||
pr_info("Children list address: %llu\n", task->children);
|
data->parent_pid = task->parent->pid;
|
||||||
pr_info("Parent PID: %d\n", task->parent->pid);
|
} else {
|
||||||
|
data->parent_pid = 0;
|
||||||
|
}
|
||||||
if (!task->fs) {
|
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();
|
rcu_read_unlock();
|
||||||
return 0;
|
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)) {
|
if (IS_ERR(path)) {
|
||||||
pr_info("Failed to resolve root path\n");
|
memset(data->root_path, 0, PATH_MAX);
|
||||||
} else {
|
} 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)) {
|
if (IS_ERR(path)) {
|
||||||
pr_info("Failed to resolve PWD\n");
|
memset(data->working_directory, 0, PATH_MAX);
|
||||||
} else {
|
} else {
|
||||||
pr_info("Current Working Directory: %s\n", path);
|
memcpy(data->working_directory, path, PATH_MAX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
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;
|
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);
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/limits.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -12,8 +13,20 @@
|
|||||||
|
|
||||||
#define __NR_get_pid_info 463
|
#define __NR_get_pid_info 463
|
||||||
|
|
||||||
long get_pid_info_syscall(int pid) {
|
struct pid_info {
|
||||||
return syscall(__NR_get_pid_info, pid);
|
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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
@ -21,6 +34,22 @@ int main(int argc, char *argv[]) {
|
|||||||
printf("Usage: %s [pid]\n", argv[0]);
|
printf("Usage: %s [pid]\n", argv[0]);
|
||||||
return -1;
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user