【问题标题】:finding the username in a linux system call在 linux 系统调用中查找用户名
【发布时间】:2015-09-17 21:57:37
【问题描述】:

我向 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 标头中进行了搜索,但找不到与用户名有关的任何内容。 谁能帮我解决这个问题?

【问题讨论】:

    标签: linux kernel system-calls


    【解决方案1】:

    您没有找到它的原因是因为没有:task_struct,而且一般内核不会在内存中保存与给定用户 ID 对应的用户名信息。这是完全没有必要的,会增加界面和代码的混乱,并且会消耗内存而没有任何额外的好处:关于用户的所有内容都用数字用户 ID 表示和存储。比较容易,节省内存。

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 感谢用户空间的概念。
      【解决方案3】:

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

      您可能想要跟踪“getent”和“id”等命令。另请查看 lib 调用 getpwuid()。通常,如果不总是,系统调用(内核空间)处理 uid。

      【讨论】:

      • 感谢用户空间的概念。
      【解决方案4】:

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

      我不禁要问你这个循环是从哪里得到的,因为它显然非常低效。在这里迭代所有进程的理由是 0,并且可以通过读取也必须找到它的系统调用的源来轻松找到获取给定 pid 的 task_struct 的方法 - 例如杀死(2)

      最后,我还必须注意有问题的代码显然是不正确的。 copy_to_user 可能会导致页面错误,您在 rcu 临界区中无法处理该错误。我敢肯定,只要您启用了调试选项,即使没有发生错误,内核也会告诉您。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-03
        • 2014-06-08
        • 1970-01-01
        • 2012-06-30
        • 1970-01-01
        • 1970-01-01
        • 2011-04-22
        • 2016-05-12
        相关资源
        最近更新 更多