put_user () ядро ​​Linux - PullRequest
       5

put_user () ядро ​​Linux

3 голосов
/ 04 апреля 2011

После выполнения put_user(message[i], buf+i); как я могу получить доступ к сообщению из пространства пользователя?

Я действительно не понимаю, откуда нужно получить доступ к строковому сообщению и что я могу с ним сделать?

Ответы [ 2 ]

6 голосов
/ 04 апреля 2011

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), это может быть буферный аргумент для нового системного вызова, который вы создаете, у вас есть много вариантов.

3 голосов
/ 04 апреля 2011

put_user (x, ptr). Здесь x - это значение для копирования в пространство пользователя, а ptr - адрес назначения в пространстве пользователя.

Таким образом, в пользовательском приложении к сообщению можно получить доступ buf+i.

...