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:
@ -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(¤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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user