gpt4 book ai didi

c - 如何使用自定义内核模块中的函数?

转载 作者:太空宇宙 更新时间:2023-11-04 07:09:36 25 4
gpt4 key购买 nike

我已经成功实现了自定义系统调用 getpuid(),现在我需要编写一个自定义动态加载模块来导出一个与自定义系统调用具有完全相同功能的函数getpeuid() 此系统调用用于获取调用进程的父进程的 euid。以及自定义模块的段:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/printk.h>
#include <linux/rcupdate.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include <linux/cred.h>

static int *getpeuid(pid_t pid, uid_t *uid)
{
// Code to get the parent process euid
......;
}

EXPORT_SYMBOL(getpeuid);

/* This function is called when the module is loaded. */
int getpeuid_init(void)
{
printk(KERN_INFO "getpeuid() loaded\n");

return 0;
}

/* This function is called when the module is removed. */
void getpeuid_exit(void) {
printk(KERN_INFO "Removing getpeuid()\n");
}

/* Macros for registering module entry and exit points. */
module_init( getpeuid_init );
module_exit( getpeuid_exit );

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Return parent euid.");
MODULE_AUTHOR("CGG");

我已成功编译此自定义模块并将模块插入内核。然后,我编写了一个测试来测试从实现的可加载内核模块导出的函数的功能:

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
pid_t pid;
uid_t *uid;

uid = (uid_t *)malloc(sizeof(uid_t));

pid = getppid();
int retval = getpeuid(pid, uid);

if( retval < 0 )
{
perror("My system call returned with an error code.");
}

printf("My syscall's parameters: %ld \n", pid);
printf("My system call returned %d.\n", retval);
printf("Current values: uid=%ld \n", *uid);
return 0;
}

但是当我编译测试脚本时,它给了我以下错误:

/tmp/ccV8WTx0.o: In function 'main': hw5-test.c:(.text+0x33): undefined reference to `supermom' collect2: error: ld returned 1 exit status

我使用cat/proc/kallsyms检查了系统中的可用符号,我导出的符号在那里:

fa0eb000 T getpeuid [getpeuid]

我只是不知道我应该如何使用我的自定义函数,因为我没有要包含在我的测试脚本中的自定义模块的头文件。即使我需要写头文件,我也不知道如何为自定义内核模块编写头文件。

有人可以帮我一下吗?

提前致谢!

编辑:

我只被允许使用可动态加载的内核模块来模拟系统调用的功能。

编辑:

不允许修改模块初始化代码中的系统调用表。

我从别人那里得到以下链接作为提示:

https://www.linux.com/learn/linux-career-center/31161-the-kernel-newbie-corner-kernel-symbols-whats-available-to-your-module-what-isnt

最佳答案

使用系统文件系统

检查 list of various Linux kernel <--> Userspace interfaces .

To allow userspace to interact with a loadable kernel module, consider using sysfs.

要在可加载模块中添加对 sysfs 的支持,请查看 a sys-fs entry 的基础知识.

best practices of creating sysfs entries 的好指南应该让你以正确的方式开始。

然后用户空间测试将从

int retval = getpeuid(pid, uid);

使用openwrite()read()
像普通文件一样与 sysfs 条目交互。
(为什么要归档?因为 everything is a file on UNIX 。)

您可以将其进一步简化为使用一个 shell 脚本,该脚本使用 echo/cat 命令通过 sysfs 条目从可加载内核模块传递/收集数据。


备选方案:美丽/丑陋的 Hack

免责声明:我同意尝试在可加载内核模块中使用系统调用既不是合适的解决方案,也不能保证始终有效。我知道我在做什么。
(将鼠标悬停在以下区 block 上,如果您同意以上内容)

检查这个 answer 和相关 code 描述了一个潜在的“hack”,允许在内核当前系统调用表中任何未使用位置的可加载模块中实现自定义系统调用。

还要仔细阅读对此 question 的几个答案/评论.他们处理克服无法修改系统调用表的问题。其中一条评论还强调了这样一个事实,即实现自己扩展的管理程序不太可能受到这种“利用”的影响,因为它们可以更好地保护系统调用表。

请注意,此类非标准接口(interface)可能并不总是有效,即使有效,它们也可能随时停止工作。坚持使用标准接口(interface)以确保可靠性。

关于c - 如何使用自定义内核模块中的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29453784/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com