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?
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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With