Meh*_*dad 8 c linux file-permissions kernel-module
我正在编写内核模块(Linux中的C),我想更改其中的其他文件的权限.任何解决方案 因为我在内核中我不能使用chmod系统调用...并感谢您的帮助
这是我的Makefile:
> obj-m += ca.o
>
> all:
> make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
>
> clean:
> make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
> #include <linux/string.h>
> #include <linux/mm.h>
> /* Snip, tons of includes (all of them :))*/
> #include <linux/delay.h> .... int procfile_write(struct file *file,
> const char *buffer, unsigned long
> count,
> void *data) { ... sys_chmod(path, per); ... } ...
Run Code Online (Sandbox Code Playgroud)
当它发出警告时:
WARNING: "sys_chmod" [file] undefiened
当使用"sudo insmod"加载模块时,它会出现以下错误:
Unknown sybol in module
似乎这个错误特别发生在内核模块中.任何的想法?再次感谢!
欢迎来到stackoverflow!IIRC你想要的sys_chmod()
来自Linux内核邮件列表
在2003年2月20日星期四,晚上11:10:27 + 0100,Andrea Arcangeli写道:2003年2月20日星期四下午12:40:43 -0500,Jeff Garzik写道:
在2003年2月20日星期四下午11:04:37 +0530,Prasad写道:
有没有办法可以在内核空间中调用系统调用?系统调用将伪装成另一个进程.实际上
调用sys_whatever().查看内核代码以获取示例.
内核已经在各个地方做到了这一点.sys_read,sys_write,open_filp,sys_close和其他函数可以安全地从内核代码调用 - 尽管不鼓励这样做.init/do_mounts.c是一个特别恼人的案例,也是klibc需要合并的一个重要原因.系统调用应该来自用户空间,而不是内核.
人们开始担心,因为这不是你在内核中可能做的事情(除非你使用你知道你在做什么).如果您只想更改某个事件的权限,请使用inotify或类似内容从用户空间执行此操作.
免责声明:
以下是我在另一个使用sys_*调用的内核模块中找到的代码:
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/syscalls.h>
/* Snip */
int openflags = O_WRONLY|O_CREAT;
if (ml != 1)
openflags |= O_TRUNC;
wfd = sys_open(collected, openflags, mode);
if (wfd >= 0) {
sys_fchown(wfd, uid, gid);
sys_fchmod(wfd, mode);
state = CopyFile;
}
Run Code Online (Sandbox Code Playgroud)
还发现:
asmlinkage long sys_rename(const char __user *oldname, const char __user *newname);
asmlinkage long sys_chmod(const char __user *filename, mode_t mode);
asmlinkage long sys_fchmod(unsigned int fd, mode_t mode);
Run Code Online (Sandbox Code Playgroud)
在 include/linux/syscalls.h
请注意,自从我做任何内核之后已经有一段时间了.例如,检查这是chmod东西的适当接口,并且你不会缩短可能实现安全钩子的任何其他调用.
此外,此链接包含有关系统调用及其符号的信息.另外,这里是用户空间API系统调用的快速参考,以及它们在内核中的实现.
系统调用不是导出的符号。如果你想要的话,你需要做一些黑客工作。
你想要动手sys_call_table。它包含一个指向每个系统调用的指针。查看arch/x86/kernel/syscall_table_32.S或arch/i386/kernel/entry.S旧内核。
您可以grep sys_call_table /usr/src/linux/System.map(或者/proc/kallsyms如果符号已导出)找到该表的基地址。您可以将此地址作为模块的参数(需要将十六进制字符串转换为指针)。
您将能够使用arch/x86/include/asm/unistd_32.h(或include/asm-i386/unistd.h在旧内核上)定义的偏移量来调用正确的系统调用。你会得到类似的东西:#define __NR_chmod 15
宏很有帮助:
#define DO_SYSCALL_2(sc, t1, a1, t2, a2) \
(((asmlinkage long (*)(t1, t2)) sys_call_table[__NR_##sc]) (a1, a2));
#define USER_SYSCALL_2(sc, t1, a1, t2, a2) \
static inline asmlinkage long syscall_##sc(t1 a1, t2 a2) \
{ return DO_SYSCALL_2(sc, t1, a1, t2, a2) }
USER_SYSCALL_2(chmod, const char __user *, filename, mode_t, mode);
int my_code(void) { return syscall_chmod(arg1, arg2); }
Run Code Online (Sandbox Code Playgroud)
另外,如果您传递的内核缓冲区(例如文件名)应该是用户缓冲区,请不要忘记更改数据段:
mm_segment_t oldfs = get_fs(); set_fs(KERNEL_DS);
ret = syscall_XXX(...);
set_fs(oldfd);
Run Code Online (Sandbox Code Playgroud)