【问题标题】:How to get userID when writing Linux kernel module编写Linux内核模块时如何获取用户ID
【发布时间】:2018-05-12 05:03:18
【问题描述】:

这是我在内核模块中的函数,我在稍后阶段使用insmod 命令在make 之后插入。我正在处理goldfish (2.6.29)

asmlinkage long our_sys_read(unsigned int fd, char  *buf, size_t count)
{
      printk("------->> our_sys_read getuid() ---------- %d\n", getuid());

      return original_call_read(fd,buf,count);
}

我想捕获系统调用并找出是哪个用户进行了这些系统调用。但是当我运行'make'时,它会引发以下错误。

/home/mohsin/LKM/trapcall.c:245: error: implicit declaration of function 'getuid'

任何建议都将不胜感激。

【问题讨论】:

    标签: c linux-kernel


    【解决方案1】:

    你也许可以用这个:

     #include <include/linux/cred.h>
    
     static int getuid()
     {
         return current_uid();
     }
    

    cred 代表“凭据”,此宏返回当前活动凭据的用户 ID。但是请记住,“当前用户 id”在 Linux 中可能意味着多种含义。

    [dan3 显然不需要像我那样挖掘那么多代码来找到这个 - 否则他比我先开始!]

    【讨论】:

    • 我以前用过它,但我不能说我完全记得它:)
    • 我已经测试了这段代码,它编译得非常好。但是当我使用 insmod 插入我的模块时,它会打印以下 UID,我猜这是错误的。 ------->> our_sys_read getuid() ---------- -1035134260 -------->> our_sys_read getuid() ---------- -943124788
    • 嗯。听起来有点不公平。您的实际用户的用户 ID 是什么?
    • 嗯..如果我告诉你我正在开发 Android 内核,我相信你的答案不会有所不同。我已签入包含已安装应用程序的所有用户 ID 列表的 packages.xml 文件。他们都没有这两个用户ID。它们从 10000 开始,然后递增 1。
    • 我相信用户 ID 是用户 ID 和“命名空间”的组合,但它仍然不能解释你得到的数字 - 我认为。
    【解决方案2】:

    花了两天时间,我终于想通了如何获取进行系统调用的进程的uid。我将给出我在不同链接上找到的所有建议,以便如果我的解决方案不起作用,其他解决方案之一可能会起作用。

    1) 正如告诉我的马茨,

    #include <include/linux/cred.h>
    
     static int getuid()
     {
         return current_uid();
     }
    

    你调用这个函数来获取 uid,但它给了我像 -943124788 这样的负数。

    2)

    uid_t credd_uid ;
    const struct cred *cred = current_cred();
    credd_uid = current->cred->uid; 
    

    与大负数一样的输出。

    3)

    uid_t struct_uid;
    struct user_struct *u = current_user();
    
    struct_uid = get_uid(u);
    

    4) 可行的解决方案

    实际上是here

    i) 在顶部声明函数原型

    asmlinkage int (*getuid_call)();
    

    ii) 将以下行添加到 init_module() 函数

    /* 获取getuid的系统调用*/

      getuid_call = sys_call_table[__NR_getuid];
    

    iii) 在你被困的系统调用函数中调用该函数以获取类似的 uid

    uid_t uid = getuid_call();
    

    【讨论】:

    • 看起来很难..看看这段代码是怎么做的:drivers/android/binder.c:binder_ioctl_set_ctx_mgr()
    【解决方案3】:

    需要调用current_uid(),定义在linux/cred.h中(2.6开始,以前是current->uid)。见kernel doc about credentials

    当前是macro,顺便说一句。

    【讨论】:

      【解决方案4】:

      在不使用 getuid 系统调用挂钩的情况下获取 UID:

      #include "linux/cred.h"
      
      static inline uid_t get_uid(void) {
      #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
      #include "linux/uidgid.h"
          // current_uid() returns struct in newer kernels
          return __kuid_val(current_uid());
      #else
          return 0 == current_uid();
      #endif
      }
      

      您还应该查看linux/uidgid.h 中定义ROOT uid/gid 的有用宏以及内联比较函数以避免直接调用__kuid_val()

      例如,一个常见的用途是检查用户是否为 root:

      static inline bool is_root_uid(void) {
      #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
      #include "linux/uidgid.h"
          // current_uid() returns struct in newer kernels
          return uid_eq(current_uid(), GLOBAL_ROOT_UID);
      #else
          return 0 == current_uid();
      #endif
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-27
        • 1970-01-01
        • 2022-01-06
        • 2012-02-22
        • 1970-01-01
        • 1970-01-01
        • 2011-05-03
        • 2015-09-21
        相关资源
        最近更新 更多