如何在编写Linux内核模块时获取userID

5

这是我的内核模块中的函数,我使用insmod命令在稍后的阶段在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'

任何建议都将不胜感激。
4个回答

6

经过两天的努力,我终于弄清楚了如何获取执行系统调用的进程的uid。我会给出我在不同链接上找到的所有建议,以便如果我的解决方案不起作用,其他方案可能有效。

1) 如Mats所告诉我的,

#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) 解决方案

实际上,这里提供了一个链接:http://www.faqs.org/docs/kernel/x931.html

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() - kaiwan

6
你可以尝试使用这个方法:
 #include <include/linux/cred.h>

 static int getuid()
 {
     return current_uid();
 }

cred代表"凭证",这个宏会返回当前活动凭证的用户ID。但是请注意,在Linux中,“当前用户ID”可能意味着多种不同的东西。

[dan3显然不需要像我一样挖掘那么多代码才能找到这个 - 或者他比我早开始!]


我以前用过它,但我不能立刻想起来 :) - dan3
我已经测试了这段代码,编译非常顺利。但是当我使用insmod插入我的模块时,它会打印出以下UID,我猜想是错误的。 ------->> our_sys_read getuid() ---------- -1035134260 ------->> our_sys_read getuid() ---------- -943124788 - Junaid
嗯,说实话有点不对劲。你实际用户的用户 ID 是多少? - Mats Petersson
嗯...如果我告诉你我正在做Android内核开发,你的答案可能不会有所不同。我已经检查了packages.xml文件,其中包含所有已安装应用程序的userID列表。它们中没有这两个userID。它们从10000开始递增一。 - Junaid
这很奇怪。current_uid() 应该有效,因为它只是一堆宏来获取当前任务的凭据。至于在你的测试中 UID 是什么,我不确定你应该期望什么。 - Mats Petersson
显示剩余3条评论

5
你需要调用current_uid(),它定义在linux/cred.h中(从2.6开始使用,之前是current->uid)。请参阅有关凭证的内核文档
顺便说一下,current是一个

1

不使用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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接