【问题标题】:get pid from sk_buff using proper wrapper function使用适当的包装函数从 sk_buff 获取 pid
【发布时间】:2021-08-26 06:24:39
【问题描述】:

这是Getting PID from sk_buff and inode in Linux Kernel的后续问题, 而且由于我无法在答案下发表评论,所以我在这里..

答案是skb->sk->socket->file->f_owner->pid

我之所以这么问,是因为我有一种预感,在内核空间中使用指针直接处理数据很容易出错。

我用谷歌搜索了这个,但没有发现任何有用的东西。

任何帮助或建议将不胜感激。

顺便说一下,内核版本是4.4或3.10。基于最新内核头的解决方案也可以。

【问题讨论】:

    标签: c linux module linux-kernel kernel


    【解决方案1】:

    由于我本周正在使用 5.10.28 和 Debian 11,这就是您得到的解决方案。 :-@) 来自 /usr/include/linux/pid.h(或 debian/linux-headers/usr/src/linux-headers-5.10.28/include/linux/pid.h,如果你愿意)的这条评论告诉它比我一个人做的更好:

    /*
     * What is struct pid?
     *
     * A struct pid is the kernel's internal notion of a process identifier.
     * It refers to individual tasks, process groups, and sessions.  While
     * there are processes attached to it the struct pid lives in a hash
     * table, so it and then the processes that it refers to can be found
     * quickly from the numeric pid value.  The attached processes may be
     * quickly accessed by following pointers from struct pid.
     *
     * Storing pid_t values in the kernel and referring to them later has a
     * problem.  The process originally with that pid may have exited and the
     * pid allocator wrapped, and another process could have come along
     * and been assigned that pid.
     *
     * Referring to user space processes by holding a reference to struct
     * task_struct has a problem.  When the user space process exits
     * the now useless task_struct is still kept.  A task_struct plus a
     * stack consumes around 10K of low kernel memory.  More precisely
     * this is THREAD_SIZE + sizeof(struct task_struct).  By comparison
     * a struct pid is about 64 bytes.
     *
     * Holding a reference to struct pid solves both of these problems.
     * It is small so holding a reference does not consume a lot of
     * resources, and since a new struct pid is allocated when the numeric pid
     * value is reused (when pids wrap around) we don't mistakenly refer to new
     * processes.
     */
    

    检查 pid.h 会显示一些对您有帮助的实用程序,如果您准备在内核空间中处理此问题(鉴于上面的黑暗警告,需要稍微了解命名空间等)。您的 sk_buff 包含一个指向 struct pid 的指针,而不仅仅是一个整数 pid,并且可能是一个用户空间进程,由于您在内核空间中,该进程现已消失。您最好的选择是:

    #include <pid.h>
    
    struct pid *myspid;
    pid_t mypid;
    
    myspid = get_pid(skb->sk->socket->file->f_owner->pid);
    if (myspid == NULL)
        /* forget it */
    mypid = pid_nr(myspid);
    return mypid;
    

    但肯定不止于此。只是让你进入球场。

    【讨论】:

    • 感谢您的意见。我实际上是在寻找一种从struct sk_buff 获取struct pid 的方法。直接使用指针操作数据会导致内核恐慌,因此是个问题。但是我发现来自struct pid 的pid 信息代表了来自套接字的指定接收者 数据,而不是实际的套接字文件所有者。还是谢谢你。
    猜你喜欢
    • 2015-05-04
    • 2021-09-29
    • 2015-11-28
    • 2018-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多