linux - put_user() linux 内核

标签 linux linux-kernel kernel

在执行 put_user(message[i], buf+i); 之后 我如何从用户空间访问消息?

我真的不明白从哪里访问字符串消息以及我可以用它做什么?

最佳答案

put_user() 只能在进行系统调用的进程的上下文中调用。

考虑一个调用 ptrace(2) 的应用程序(参见 kernel/ptrace.c)。

内核将调用特定于体系结构的 ptrace 帮助程序:

SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
            unsigned long, data) 
{
    /* arch-independent code */
    /* ... */
    ret = arch_ptrace(child, request, addr, data);

在x86平台上,arch_ptrace()定义在arch/x86/kernel/ptrace.c中:

long arch_ptrace(struct task_struct *child, long request,
             unsigned long addr, unsigned long data)
{
    int ret;
    unsigned long __user *datap = (unsigned long __user *)data;

    switch (request) {
    /* read the word at location addr in the USER area. */
    case PTRACE_PEEKUSR: {
            unsigned long tmp;

            ret = -EIO;
            if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user))
                    break;

            tmp = 0;  /* Default return condition */
            if (addr < sizeof(struct user_regs_struct))
                    tmp = getreg(child, addr);
            else if (addr >= offsetof(struct user, u_debugreg[0]) &&
                     addr <= offsetof(struct user, u_debugreg[7])) {
                    addr -= offsetof(struct user, u_debugreg[0]);
                    tmp = ptrace_get_debugreg(child, addr / sizeof(data));
            }
            ret = put_user(tmp, datap);
            break;
    }

当进程调用ptrace(2) 并要求执行PTRACE_PEEKUSR 时,内核需要将信息(ret) 返回给用户。内核使用指向用户提供的缓冲区datap 指针来了解在进程中的何处写入tmp 的值。

几乎所有调用 put_user() 的情况都会由用户态进程启动。向用户空间发送信号是一个明显的区别,内核发起发送信号,但是内核有代码(参见arch/x86/kernel/signal.c函数__setup_frame()) 找到堆栈帧并将处理信号的需要写入其中。

因此,经过长篇大论的讨论:您将通过您提供给内核写入的任何缓冲区访问进程中的数据——它可以是特定于驱动程序的缓冲区ioctl(2),它可以是您创建的新系统调用的缓冲区参数,您有很多选择。

关于linux - put_user() linux 内核,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5536486/

相关文章:

kernel - EasyHook 内核模式 Hook

linux - 如何从 "struct linux_binprm"获取 argv?

linux - 用冒号分隔子列表

linux - 确定哪个名称服务器执行了解析

linux - 将 WindowsForms 项目从 Visual Studio 迁移到 Linux 上的 MonoDevelop,没有错误。为什么应用程序运行速度很慢?

c - 如何在内核代码中获取子进程列表

c - 如何将 LKM(可加载内核模块)链接到静态或动态库?

linux - 如何从 inode /路径名中找到一个 dentry?

c - 判断是ipv4还是ipv6数据结构

linux - 如何将环境设置导入我的 Perl 程序?