在Linux系统调用中find用户名

我已经添加了一个系统调用到Linux内核看起来像这样:

#include <linux/kernel.h> #include <linux/sched.h> #include <linux/list.h> #include <linux/cred.h> #include <asm/uaccess.h> asmlinkage int sys_os_pid_to_uid(int pid, int* puid) { struct task_struct* task; rcu_read_lock(); for_each_process(task) { if (task->pid == (pid_t) pid) { copy_to_user(puid, &(task->cred->uid.val), sizeof(task->cred->uid.val)); } } rcu_read_unlock(); return 0; } 

它获得一个进程ID( pid ),并确定执行它的用户的用户ID( puid )。

现在,我的问题开始了:我想为这个系统调用添加另一个参数,即char *username ,它将包含ID为puid的用户的用户名。 我在cred.h头文件search,但无法find任何有关的用户名。 谁能帮我解决这个问题吗?

你没有找到它的原因是因为没有一个: task_struct ,而内核通常不会保存关于给定用户ID对应的用户名的内存信息。 这是完全不必要的,会增加界面和代码的混乱,并且会消耗内存而没有任何额外的好处:关于用户的所有事情都用数字用户id来表示和存储。 比较容易,记忆被保存。

您不应该/不能在系统调用中执行此操作。

我建议你编写一个包装用户空间函数,调用你的系统调用,然后调用getpwuid(3)getpwuid_r(3)将用户ID转换为用户名。 请注意,这是在用户空间而不是在内核空间中完成的。

内核不知道用户名; 它只处理用户ID。 将用户名解析为用户ID(反之亦然)完全由用户空间的getpwent()系列libc函数( getpwuid()getpwnam()等)处理。

请注意,您的系统调用有点多余, 通过调用/proc/$pid上的stat()或读取/proc/$pid/status来获取进程的用户标识已经很简单了。

我很确定用户名的唯一的概念是在用户空间,基于/ etc / passwd(通常,但可以是其他来源,如NIS或LDAP)。 如果在/ etc / passwd中更改现有条目的用户名,用户将立即成为新的用户名,就像更改/ etc / hosts中的主机名条目从本地计算机的角度更改IP地址的有效主机名一样。 它只是一个查找/名称解析。 存储对象将全部包含用户标识,而不是用户名。

您可能想要追踪“getent”和“id”等命令。 也看看lib调用getpwuid()。 通常,如果不是一直,syscalls(内核空间)处理uid。

但是这是什么意思呢? 你只是玩内核? uid可以在/ proc中找到。 正如其他人所指出的,用户名必须在用户空间中解决。

我不禁要问,你是从哪里来的,因为这显然非常低效。 在这里遍历所有进程的原因是0,并且通过读取系统调用的来源也可以很容易地找到给定pid的task_struct,例如kill(2)

最后,我还必须注意,有问题的代码是不正确的。 copy_to_user会导致页面错误,在rcu关键部分不能使用。 我很确定内核会告诉你,即使没有发生故障,只要你有调试选项启用。