更改内核中的文件权限

发布于 2024-08-03 04:49:58 字数 935 浏览 5 评论 0原文

我正在编写内核模块(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

这是我的代码:

> #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); ... } ...

制作时给出警告:

警告:“sys_chmod”[文件]未定义

并且当使用“sudo insmod”加载模块时,会出现以下错误:

模块中的未知符号

看来这个错误尤其发生在内核模块中。有什么想法吗?再次感谢!

I am writing kernel module(C in Linux) and I want to change the permission of the other files in it.
any solution?
since I am in kernel I can't use chmod syscall and ...
thanks for your help

This is my 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

And this is my Code:

> #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); ... } ...

When Making it gives a warning:

WARNING: "sys_chmod" [file] undefiened

and when loading the module with "sudo insmod" it gives this error:

Unknown sybol in module

it seems that this error happens especialy in kernel modules. any idea? again thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你是我的挚爱i 2024-08-10 04:49:58

欢迎来到 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()。查看内核代码的示例。

内核已经这样做了
各个地方。系统读、系统写、
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;
}

还发现:

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);

include/linux/syscalls.h

请注意,自从我这样做以来已经有一段时间了任何内核的东西。例如,检查这是否是 chmod 内容的适当接口,并且您没有快捷方式执行任何其他可能实现安全挂钩的调用。

另外,此链接包含有关系统调用的信息和他们的符号。另外此处 是用户空间 API 系统调用及其在内核中实现位置的快速参考。

Welcome to stackoverflow! IIRC you want sys_chmod()

From the Linux Kernel Mailing List

On Thu, Feb 20, 2003 at 11:10:27PM +0100, Andrea Arcangeli wrote:
On Thu, Feb 20, 2003 at 12:40:43PM -0500, Jeff Garzik wrote:

On Thu, Feb 20, 2003 at 11:04:37PM +0530, Prasad wrote:

Is there a way using which i could invoke a syscall in the kernel
space? The syscall is to be run disguised as another process. The actual

Call sys_whatever(). Look at the kernel code for examples.

The kernel already does this in
various places. sys_read, sys_write,
open_filp, sys_close, and other
functions are safe to call from kernel
code -- though this is discouraged.
init/do_mounts.c is a particularly
annoying case, and is a big reason why
klibc needs to be merged. syscalls
should be made from userspace, not the
kernel.

People are starting to worry, as this isn't the kind of thing you might do in the kernel (unless you are use you know what you are doing). If you just want to change permissions on a certain event, do it from userspace with inotify or similar.

Disclaimer aside:

Here is some code I found in another kernel module, which uses the sys_* calls:

#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;
}

Also found:

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);

in include/linux/syscalls.h

Mind you, it has been a while since I did any kernel stuff. Check that this is the appropriate interface for chmod stuff and that you arn't shortcutting any other call that might implement security hooks, for example.

Also, This link contains information on syscalls and their symbols. Also Here is a quick-reference of user-space API system calls and where they are implemented in the kernel.

遥远的绿洲 2024-08-10 04:49:58

系统调用不是导出的符号。如果你想要的话,你需要做一些黑客工作。

您想了解sys_call_table。它包含一个指向每个系统调用的指针。
查看旧内核上的 arch/x86/kernel/syscall_table_32.Sarch/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); }

另外,如果您传递应该是用户缓冲区的内核缓冲区(例如文件名),请不要忘记更改数据部分:

mm_segment_t oldfs = get_fs(); set_fs(KERNEL_DS);
ret = syscall_XXX(...);
set_fs(oldfd);

The syscalls are not exported symbols. You need to do a little bit of hacking if you want them.

you want to get your fingers on sys_call_table. It contains a pointer to every syscall.
Look at arch/x86/kernel/syscall_table_32.S or arch/i386/kernel/entry.S on older kernels.

You can grep sys_call_table /usr/src/linux/System.map (or /proc/kallsyms if the symbols are exported) to find the base address of this table.
You can have this address as a parameter for your module (converting an hex string to a pointer will be needed).

You'll be able to call the right syscall with the offset defined in arch/x86/include/asm/unistd_32.h (or include/asm-i386/unistd.h on older kernels).
You get something like: #define __NR_chmod 15

Macros are helpful:

#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); }

Also, if you are passing kernel buffer (for filename for examples) that are supposed to be user buffers, don't forget to change the data segment:

mm_segment_t oldfs = get_fs(); set_fs(KERNEL_DS);
ret = syscall_XXX(...);
set_fs(oldfd);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文