All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Weinberger <richard@nod.at>
To: "Mickaël Salaün" <mic@digikod.net>, linux-kernel@vger.kernel.org
Cc: Jonathan Corbet <corbet@lwn.net>, Jeff Dike <jdike@addtoit.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "H . Peter Anvin" <hpa@zytor.com>,
	x86@kernel.org, Kees Cook <keescook@chromium.org>,
	Andy Lutomirski <luto@amacapital.net>,
	Will Drewry <wad@chromium.org>,
	Shuah Khan <shuahkh@osg.samsung.com>,
	Chris Metcalf <cmetcalf@ezchip.com>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Andrew Morton <akpm@linux-foundation.org>,
	James Hogan <james.hogan@imgtec.com>,
	Thomas Meyer <thomas@m3y3r.de>,
	Nicolas Iooss <nicolas.iooss_linux@m4x.org>,
	Anton Ivanov <aivanov@brocade.com>,
	linux-doc@vger.kernel.org,
	user-mode-linux-devel@lists.sourceforge.net,
	user-mode-linux-user@lists.sourceforge.net,
	linux-api@vger.kernel.org,
	Meredydd Luff <meredydd@senatehouse.org>,
	David Drysdale <drysdale@google.com>
Subject: Re: [PATCH v1 1/4] um: Fix ptrace GETREGS/SETREGS bugs
Date: Mon, 21 Dec 2015 11:13:33 +0100	[thread overview]
Message-ID: <5677D0CD.1070602@nod.at> (raw)
In-Reply-To: <5677C526.5070803@digikod.net>

[-- Attachment #1: Type: text/plain, Size: 1090 bytes --]

Am 21.12.2015 um 10:23 schrieb Mickaël Salaün:
>>>> Doesn't this break the support for changing syscall numbers using PTRACE_SETREGS?
>>>
>>> The logic is unchanged except updating the UPT_SYSCALL_NR before syscall_trace_enter(). I did my last tests with the x86_32 subarchitecture and all tests (from selftest/seccomp), including PTRACE_SETREGS for syscall numbers tests, passed. However, 2 of this tests still fail for x86_64 (only).
>>
>> No, the logic is different.
>> syscall_trace_enter(regs) enters the ptrace() path and here registers can be changed.
>> Hence "syscall = UPT_SYSCALL_NR(r);" will see the old syscall number.
>> UPT_SYSCALL_NR() returns the syscall number before the ptrace() path...
> 
> The thing is, PTRACE_SETREGS give access to *orig_ax* in the user_regs_struct from arch/x86/include/asm/user_*.h and selftest/seccomp only update this (virtual) register, not the EAX/RAX. Am I missing something?

Sorry, meant orig...

Please see the attached program. It proves that your patch is breaking stuff.
The test is extracted from UML's selftests.

Thanks,
//richard

[-- Attachment #2: ptsc.c --]
[-- Type: text/x-csrc, Size: 4641 bytes --]

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <sys/syscall.h>
#include <sys/reg.h>

#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
#define PT_OFFSET(r) ((r) * sizeof(long))
#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_RAX)
#define PTRACE_OLDSETOPTIONS      21

static void ptrace_child(void)
{
        int ret;
        int pid = syscall(__NR_getpid), ppid = getppid();
        int sc_result;

        if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
                perror("ptrace");
                kill(pid, SIGKILL);
        }
        kill(pid, SIGSTOP);

        /*
         * This syscall will be intercepted by the parent. Don't call more than
         * once, please.
         */
        sc_result = syscall(__NR_getpid);

        if (sc_result == pid)
                /* Nothing modified by the parent, we are running normally. */
                ret = 1;
        else if (sc_result == ppid)
                /*
                 * Expected in check_ptrace and check_sysemu when they succeed
                 * in modifying the stack frame
                 */
                ret = 0;
        else
                /* Serious trouble! This could be caused by a bug in host 2.6
                 * SKAS3/2.6 patch before release -V6, together with a bug in
                 * the UML code itself.
                 */
                ret = 2;

        exit(ret);
}

static int stop_ptraced_child(int pid, int exitcode, int mustexit)
{
        int status, n, ret = 0;

        if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) {
                perror("stop_ptraced_child : ptrace failed");
                return -1;
        }
        CATCH_EINTR(n = waitpid(pid, &status, 0));
        if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
                int exit_with = WEXITSTATUS(status);
                if (exit_with == 2)
                        printf("check_ptrace : child exited with status 2. "
                                  "\nDisabling SYSEMU support.\n");
                printf("check_ptrace : child exited with exitcode %d, while "
                          "expecting %d; status 0x%x\n", exit_with,
                          exitcode, status);
                if (mustexit)
                        exit(1);
                ret = -1;
        }

        return ret;
}


static int start_ptraced_child(void)
{
        int pid, n, status;

        pid = fork();
        if (pid == 0)
                ptrace_child();
        else if (pid < 0)
                printf("start_ptraced_child : fork failed");

        CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
        if (n < 0)
                printf("check_ptrace : waitpid failed");
        if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
                printf("check_ptrace : expected SIGSTOP, got status = %d",
                      status);

        return pid;
}

static void check_ptrace(void)
{       
        int pid, syscall, n, status;
        
        printf("Checking that ptrace can change system call numbers...");
	fflush(stdout);

        pid = start_ptraced_child();

        if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
                   (void *) PTRACE_O_TRACESYSGOOD) < 0))
                printf("check_ptrace: PTRACE_OLDSETOPTIONS failed");

        while (1) {
                if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
                        printf("check_ptrace : ptrace failed");
                
                CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
                if (n < 0)
                        printf("check_ptrace : wait failed");
                
                if (!WIFSTOPPED(status) ||
                   (WSTOPSIG(status) != (SIGTRAP | 0x80)))
                        printf("check_ptrace : expected (SIGTRAP|0x80), "
                               "got status = %d", status);
                
                syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET,
                                 0);
                if (syscall == __NR_getpid) {
                        n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
                                   __NR_getppid);
                        if (n < 0)
                                printf("check_ptrace : failed to modify "
                                             "system call");
                        break;
                }
        }
        stop_ptraced_child(pid, 0, 1);
        printf("OK\n");
}

int main(void)
{
	check_ptrace();

	return 0;
}

  reply	other threads:[~2015-12-21 10:13 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-21  0:03 [PATCH v1 0/4] um: Add seccomp support Mickaël Salaün
2015-12-21  0:03 ` Mickaël Salaün
2015-12-21  0:03 ` Mickaël Salaün
2015-12-21  0:03 ` [PATCH v1 1/4] um: Fix ptrace GETREGS/SETREGS bugs Mickaël Salaün
2015-12-21  0:03   ` Mickaël Salaün
2015-12-21  0:03   ` Mickaël Salaün
     [not found]   ` <1450656209-2676-2-git-send-email-mic-WFhQfpSGs3bR7s880joybQ@public.gmane.org>
2015-12-21  0:20     ` Richard Weinberger
2015-12-21  0:20       ` Richard Weinberger
2015-12-21  0:20       ` Richard Weinberger
2015-12-21  8:49       ` Mickaël Salaün
2015-12-21  8:56         ` Richard Weinberger
2015-12-21  8:56           ` Richard Weinberger
     [not found]         ` <5677BD23.4060602-WFhQfpSGs3bR7s880joybQ@public.gmane.org>
2015-12-21  9:00           ` Richard Weinberger
2015-12-21  9:00             ` Richard Weinberger
2015-12-21  9:00             ` Richard Weinberger
     [not found]             ` <5677BFBD.3090200-/L3Ra7n9ekc@public.gmane.org>
2015-12-21  9:23               ` Mickaël Salaün
2015-12-21  9:23                 ` Mickaël Salaün
2015-12-21 10:13                 ` Richard Weinberger [this message]
2015-12-21 19:10                   ` Mickaël Salaün
2015-12-21  0:03 ` [PATCH v1 3/4] um: Add full asm/syscall.h support Mickaël Salaün
2015-12-21  0:03   ` Mickaël Salaün
2015-12-21  0:03   ` Mickaël Salaün
     [not found] ` <1450656209-2676-1-git-send-email-mic-WFhQfpSGs3bR7s880joybQ@public.gmane.org>
2015-12-21  0:03   ` [PATCH v1 2/4] selftests/seccomp: Remove the need for HAVE_ARCH_TRACEHOOK Mickaël Salaün
2015-12-21  0:03     ` Mickaël Salaün
2015-12-21  0:03     ` Mickaël Salaün
2015-12-21  0:03   ` [PATCH v1 4/4] um: Add seccomp support Mickaël Salaün
2015-12-21  0:03     ` Mickaël Salaün
2015-12-21  0:03     ` Mickaël Salaün

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5677D0CD.1070602@nod.at \
    --to=richard@nod.at \
    --cc=aivanov@brocade.com \
    --cc=akpm@linux-foundation.org \
    --cc=cmetcalf@ezchip.com \
    --cc=corbet@lwn.net \
    --cc=drysdale@google.com \
    --cc=hpa@zytor.com \
    --cc=james.hogan@imgtec.com \
    --cc=jdike@addtoit.com \
    --cc=keescook@chromium.org \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=meredydd@senatehouse.org \
    --cc=mic@digikod.net \
    --cc=mingo@redhat.com \
    --cc=mpe@ellerman.id.au \
    --cc=nicolas.iooss_linux@m4x.org \
    --cc=shuahkh@osg.samsung.com \
    --cc=tglx@linutronix.de \
    --cc=thomas@m3y3r.de \
    --cc=user-mode-linux-devel@lists.sourceforge.net \
    --cc=user-mode-linux-user@lists.sourceforge.net \
    --cc=wad@chromium.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.