put_user() Linux 内核

发布于 2024-10-30 03:08:43 字数 101 浏览 6 评论 0原文

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

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

After doing put_user(message[i], buf+i);
how can I access message from user space?

I really don't understand where the string message is to be accessed from and what I can do with it?

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

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

发布评论

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

评论(2

甜心 2024-11-06 03:08:43

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< /code>:

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),它可能是您创建的新系统调用的缓冲区参数,您有很多选择。

put_user() should only be called in the context of a process making a system call.

Consider an application calling ptrace(2) (see kernel/ptrace.c).

The kernel will call into an architecture-specific ptrace helper:

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

On the x86 platform, arch_ptrace() is defined in 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;
    }

When a process calls ptrace(2) and asks to perform a PTRACE_PEEKUSR, the kernel needs to return information (ret) back to the user. The kernel uses the datap pointer to a user supplied buffer to know where in the process to write the value of tmp.

Almost every case of calling put_user() will be initiated by a userland process. Sending signals to userspace is an obvious difference, where the kernel initiates sending the signal, but the kernel has code (see arch/x86/kernel/signal.c function __setup_frame()) to find the stack frame and write into it the need to handle a signal.

So, after a long-winded discussion: You will access your data in your process via whatever buffer you gave to the kernel to write into -- it could be a buffer for a driver-specific ioctl(2), it could be a buffer argument to a new system call you create, you have a lot of choices.

空‖城人不在 2024-11-06 03:08:43

put_user(x, ptr)。这里 x 是要复制到用户空间的值,而 ptr 是用户空间中的目标地址。

因此,在用户应用程序中,可以通过buf+i访问该消息。

put_user (x, ptr). Here x is the value to copy to user space, while ptr is the destination address, in user space.

So in user application the message can be accessed by buf+i.

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