diff --git a/patch.diff b/patch.diff index 20f1c0f..2fa7e59 100644 --- a/patch.diff +++ b/patch.diff @@ -11,7 +11,7 @@ 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..1efb297e1 100644 +index 575810492..6c211aabc 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -1197,6 +1197,20 @@ asmlinkage long sys_ni_syscall(void); @@ -24,7 +24,7 @@ index 575810492..1efb297e1 100644 + u32 state; + const void *stack; + u64 age; -+ // int * children; ++ int *children; + int parent_pid; + char root_path[PATH_MAX]; + char working_directory[PATH_MAX]; @@ -84,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..21ff5f699 +index 000000000..f14b7e4d3 --- /dev/null +++ b/kernel/get_pid_info/get_pid_info.c -@@ -0,0 +1,76 @@ +@@ -0,0 +1,123 @@ +// +// Created by jrathelo on 11/18/24. +// @@ -107,11 +107,26 @@ index 000000000..21ff5f699 + struct task_struct *task; + char * path; + 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); + if (data == NULL) { + return -ENOMEM; + } ++ memset(data, 0, sizeof(struct pid_info)); + + int error = copy_from_user(data, p_info_struct, sizeof(struct pid_info)); + if (error) { @@ -150,14 +165,46 @@ index 000000000..21ff5f699 + } else { + 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(); ++ 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)); + if (error) { + kfree(data); + return -EFAULT; + } + kfree(data); ++ pr_info("HERE7\n"); + return 0; +} + diff --git a/src/get_pid_info.c b/src/get_pid_info.c index 7be1321..8efbe1c 100644 --- a/src/get_pid_info.c +++ b/src/get_pid_info.c @@ -15,10 +15,10 @@ struct pid_info { int pid; - u32 state; + unsigned int state; const void *stack; - u64 age; - // int * children; + unsigned long long age; + int *children; int parent_pid; char root_path[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; char * path; 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); if (data == NULL) { return -ENOMEM; } + memset(data, 0, sizeof(struct pid_info)); int error = copy_from_user(data, p_info_struct, sizeof(struct pid_info)); if (error) { @@ -71,14 +86,46 @@ static long __sys_get_pid_info(struct pid_info __user * p_info_struct, int pi } else { 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(); + 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)); if (error) { kfree(data); return -EFAULT; } kfree(data); + pr_info("HERE7\n"); return 0; } diff --git a/src/tester/main.c b/src/tester/main.c index ca9b671..b32e9e3 100644 --- a/src/tester/main.c +++ b/src/tester/main.c @@ -18,7 +18,7 @@ struct pid_info { unsigned int state; const void *stack; unsigned long long age; - // int * children; + int *children; int parent_pid; char root_path[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); } -int main(int argc, char *argv[]) { - if (argc < 2) { - printf("Usage: %s [pid]\n", argv[0]); - return -1; - } +int recurse_get_pid_info(int pid) { 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) { return ret; } @@ -45,11 +43,30 @@ int main(int argc, char *argv[]) { } 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("Age : %lld ms\n", data.age / 1000000); + printf("Stack address: %p\n", data.stack); 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); - + 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])); }