This commit is contained in:
Jolan Rathelot 2024-11-20 16:56:35 +01:00
parent 8ee8018212
commit 354f123b74
3 changed files with 127 additions and 16 deletions

View File

@ -11,7 +11,7 @@ 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..1efb297e1 100644 index 575810492..6c211aabc 100644
--- a/include/linux/syscalls.h --- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h +++ b/include/linux/syscalls.h
@@ -1197,6 +1197,20 @@ asmlinkage long sys_ni_syscall(void); @@ -1197,6 +1197,20 @@ asmlinkage long sys_ni_syscall(void);
@ -24,7 +24,7 @@ index 575810492..1efb297e1 100644
+ u32 state; + u32 state;
+ const void *stack; + const void *stack;
+ u64 age; + u64 age;
+ // int * children; + int *children;
+ int parent_pid; + int parent_pid;
+ char root_path[PATH_MAX]; + char root_path[PATH_MAX];
+ char working_directory[PATH_MAX]; + char working_directory[PATH_MAX];
@ -84,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..21ff5f699 index 000000000..f14b7e4d3
--- /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,76 @@ @@ -0,0 +1,123 @@
+// +//
+// Created by jrathelo on 11/18/24. +// Created by jrathelo on 11/18/24.
+// +//
@ -107,11 +107,26 @@ index 000000000..21ff5f699
+ struct task_struct *task; + struct task_struct *task;
+ char * path; + char * path;
+ struct timespec64 current_time; + struct timespec64 current_time;
+ size_t size = 0;
+ int *child_list = NULL;
+
+ if (p_info_struct == NULL) {
+ rcu_read_lock();
+ task = pid_task(find_vpid(pid), PIDTYPE_PID);
+ if (task) {
+ size = list_count_nodes(&(task->children));
+ rcu_read_unlock();
+ return size;
+ }
+ rcu_read_unlock();
+ return 0;
+ }
+ +
+ struct pid_info *data = (struct pid_info *) kzalloc(sizeof(struct pid_info), GFP_KERNEL); + struct pid_info *data = (struct pid_info *) kzalloc(sizeof(struct pid_info), GFP_KERNEL);
+ if (data == NULL) { + if (data == NULL) {
+ return -ENOMEM; + return -ENOMEM;
+ } + }
+ memset(data, 0, sizeof(struct pid_info));
+ +
+ int error = copy_from_user(data, p_info_struct, sizeof(struct pid_info)); + int error = copy_from_user(data, p_info_struct, sizeof(struct pid_info));
+ if (error) { + if (error) {
@ -150,14 +165,46 @@ index 000000000..21ff5f699
+ } else { + } else {
+ memcpy(data->working_directory, path, PATH_MAX); + memcpy(data->working_directory, path, PATH_MAX);
+ } + }
+ size = list_count_nodes(&(task->children));
+ if (size == 0) {
+ child_list = NULL;
+ } else {
+ child_list = kzalloc(sizeof(int) * size, GFP_KERNEL);
+ if (child_list == NULL){
+ kfree(data);
+ rcu_read_unlock();
+ return -ENOMEM;
+ }
+ struct task_struct *child_task;
+ size_t index = 0;
+ list_for_each_entry(child_task, &task->children, sibling) {
+ child_list[index] = child_task->pid;
+
+ pr_info("%d\n", child_list[index]);
+ index ++;
+ }
+ }
+ } + }
+ rcu_read_unlock(); + rcu_read_unlock();
+ if (child_list != NULL) {
+ pr_info("HERE: %d\n", child_list[0]);
+ error = copy_to_user(data->children, child_list, sizeof(int) * size);
+ if (error) {
+ pr_info("HERE?\n");
+ kfree(child_list);
+ kfree(data);
+ return -EFAULT;
+ }
+ kfree(child_list);
+ }
+ pr_info("HERE6\n");
+ error = copy_to_user(p_info_struct, data, sizeof(struct pid_info)); + error = copy_to_user(p_info_struct, data, sizeof(struct pid_info));
+ if (error) { + if (error) {
+ kfree(data); + kfree(data);
+ return -EFAULT; + return -EFAULT;
+ } + }
+ kfree(data); + kfree(data);
+ pr_info("HERE7\n");
+ return 0; + return 0;
+} +}
+ +

View File

@ -15,10 +15,10 @@
struct pid_info { struct pid_info {
int pid; int pid;
u32 state; unsigned int state;
const void *stack; const void *stack;
u64 age; unsigned long long age;
// int * children; int *children;
int parent_pid; int parent_pid;
char root_path[PATH_MAX]; char root_path[PATH_MAX];
char working_directory[PATH_MAX]; char working_directory[PATH_MAX];
@ -28,11 +28,26 @@ static long __sys_get_pid_info(struct pid_info __user * p_info_struct, int pi
struct task_struct *task; struct task_struct *task;
char * path; char * path;
struct timespec64 current_time; struct timespec64 current_time;
size_t size = 0;
int *child_list = NULL;
if (p_info_struct == NULL) {
rcu_read_lock();
task = pid_task(find_vpid(pid), PIDTYPE_PID);
if (task) {
size = list_count_nodes(&(task->children));
rcu_read_unlock();
return size;
}
rcu_read_unlock();
return 0;
}
struct pid_info *data = (struct pid_info *) kzalloc(sizeof(struct pid_info), GFP_KERNEL); struct pid_info *data = (struct pid_info *) kzalloc(sizeof(struct pid_info), GFP_KERNEL);
if (data == NULL) { if (data == NULL) {
return -ENOMEM; return -ENOMEM;
} }
memset(data, 0, sizeof(struct pid_info));
int error = copy_from_user(data, p_info_struct, sizeof(struct pid_info)); int error = copy_from_user(data, p_info_struct, sizeof(struct pid_info));
if (error) { if (error) {
@ -71,14 +86,46 @@ static long __sys_get_pid_info(struct pid_info __user * p_info_struct, int pi
} else { } else {
memcpy(data->working_directory, path, PATH_MAX); memcpy(data->working_directory, path, PATH_MAX);
} }
size = list_count_nodes(&(task->children));
if (size == 0) {
child_list = NULL;
} else {
child_list = kzalloc(sizeof(int) * size, GFP_KERNEL);
if (child_list == NULL){
kfree(data);
rcu_read_unlock();
return -ENOMEM;
}
struct task_struct *child_task;
size_t index = 0;
list_for_each_entry(child_task, &task->children, sibling) {
child_list[index] = child_task->pid;
pr_info("%d\n", child_list[index]);
index ++;
}
}
} }
rcu_read_unlock(); rcu_read_unlock();
if (child_list != NULL) {
pr_info("HERE: %d\n", child_list[0]);
error = copy_to_user(data->children, child_list, sizeof(int) * size);
if (error) {
pr_info("HERE?\n");
kfree(child_list);
kfree(data);
return -EFAULT;
}
kfree(child_list);
}
pr_info("HERE6\n");
error = copy_to_user(p_info_struct, data, sizeof(struct pid_info)); error = copy_to_user(p_info_struct, data, sizeof(struct pid_info));
if (error) { if (error) {
kfree(data); kfree(data);
return -EFAULT; return -EFAULT;
} }
kfree(data); kfree(data);
pr_info("HERE7\n");
return 0; return 0;
} }

View File

@ -18,7 +18,7 @@ struct pid_info {
unsigned int state; unsigned int state;
const void *stack; const void *stack;
unsigned long long age; unsigned long long age;
// int * children; int *children;
int parent_pid; int parent_pid;
char root_path[PATH_MAX]; char root_path[PATH_MAX];
char working_directory[PATH_MAX]; char working_directory[PATH_MAX];
@ -29,14 +29,12 @@ long get_pid_info(struct pid_info * ret, int pid) {
return syscall(__NR_get_pid_info, ret, pid); return syscall(__NR_get_pid_info, ret, pid);
} }
int main(int argc, char *argv[]) { int recurse_get_pid_info(int pid) {
if (argc < 2) {
printf("Usage: %s [pid]\n", argv[0]);
return -1;
}
struct pid_info data; struct pid_info data;
long ret = get_pid_info(&data, atoi(argv[1])); long c = get_pid_info(NULL, pid);
data.children = malloc(sizeof(int) * c);
long ret = get_pid_info(&data, pid);
if (ret) { if (ret) {
return ret; return ret;
} }
@ -45,11 +43,30 @@ int main(int argc, char *argv[]) {
} }
printf("Pid: %d\n", data.pid); printf("Pid: %d\n", data.pid);
printf("# of children: %ld\n", c);
printf("Children: [");
for(long i = 0; i < c; i++) {
printf("%d, ", data.children[i]);
}
printf("]\n");
printf("State; %d\n", data.state); printf("State; %d\n", data.state);
printf("Age : %lld ms\n", data.age / 1000000); printf("Age : %lld ms\n", data.age / 1000000);
printf("Stack address: %p\n", data.stack);
printf("Parent PID: %d\n", data.parent_pid); printf("Parent PID: %d\n", data.parent_pid);
printf("Root Path: %s\n", data.root_path); printf("Root Path: %s\n", data.root_path);
printf("Current Working Directory: %s\n", data.working_directory); printf("Current Working Directory: %s\n\n", data.working_directory);
int r = 0;
for(long i = 0; i < c; i++) {
r += recurse_get_pid_info(data.children[i]);
}
return r;
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s [pid]\n", argv[0]);
return -1;
}
return recurse_get_pid_info(atoi(argv[1]));
} }