WARNING: CPU: 0 PID: 1752 at arch/x86/kernel/traps.c:788

From: Richard Weinberger
Date: Thu Jun 01 2017 - 18:46:44 EST


Hi!

UserModeLinux hits the following warning on the host.
I've extracted the evil ptrace() command sequence, please see attached program,
it triggers the warning too.

Fun fact, it happens only when I disable KVM for that qemu instance.
i.e "qemu-system-x86_64 -M pc-q35-2.4 -cpu Broadwell" triggers while
"qemu-system-x86_64 -M pc-q35-2.4,accel=kvm -cpu Broadwell" does not...

[ 21.509213] ------------[ cut here ]------------
[ 21.510395] WARNING: CPU: 0 PID: 1752 at arch/x86/kernel/traps.c:788 do_debug+0xfe/0x1f0
[ 21.510928] Modules linked in:
[ 21.511618] CPU: 0 PID: 1752 Comm: sysemu Not tainted 4.12.0-rc3+ #81
[ 21.511903] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.9.1-0-gb3ef39f-prebuilt.qemu-project.org 04/01/2014
[ 21.512453] task: ffff9941f86f4800 task.stack: ffff9c2dc1978000
[ 21.512727] RIP: 0010:do_debug+0xfe/0x1f0
[ 21.512921] RSP: 0000:ffff9941ffc07f20 EFLAGS: 00000046
[ 21.513183] RAX: 0000000000000001 RBX: ffff9941ffc07f58 RCX: 00000000ffffffff
[ 21.513491] RDX: ffff9941ffc07ef0 RSI: 0000000000000003 RDI: ffffffff9f84f560
[ 21.513797] RBP: ffff9941ffc07f48 R08: 0000000000000000 R09: 0000000000000005
[ 21.514103] R10: ffffffffffffff90 R11: 0000000000000346 R12: ffff9941f86f4800
[ 21.514408] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[ 21.514824] FS: 00007fd3c0c74700(0000) GS:ffff9941ffc00000(0000) knlGS:0000000000000000
[ 21.515080] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 21.515243] CR2: 00007fd3c0c7c89c CR3: 00000001787e7000 CR4: 00000000003406f0
[ 21.515559] Call Trace:
[ 21.516010] <#DB>
[ 21.516290] debug+0x35/0x70
[ 21.516559] RIP: 0010:entry_SYSCALL_64+0x0/0x3
[ 21.516686] RSP: 0018:00007ffc5a414c18 EFLAGS: 00000002
[ 21.516835] RAX: 00000000000000e7 RBX: 0000000000000000 RCX: 00007fd3c076c2e9
[ 21.517024] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
[ 21.517211] RBP: 00007fd3c0a53860 R08: 000000000000003c R09: 00000000000000e7
[ 21.517408] R10: ffffffffffffff90 R11: 0000000000000346 R12: 00007fd3c0a53860
[ 21.517613] R13: 00007fd3c0a58c60 R14: 0000000000000000 R15: 0000000000000000
[ 21.517959] </#DB>
[ 21.518060] Code: 00 3d 01 80 00 00 74 b1 65 ff 05 42 16 5f 61 f6 83 91 00 00 00 02 0f 85 97 00 00 00 f6 45 d9 40 74 28 f6 83 88 00 00 00 03 75 1f <0f> ff 49 81 a4 24 28 09 00
00 ff bf ff ff 3e 41 80 0c 24 10 48
[ 21.518979] ---[ end trace 0f6aac766f3c1297 ]---

Thanks,
//richard
#define _GNU_SOURCE
#include <sys/ptrace.h>
#include <linux/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <signal.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

static void ptrace_child(void)
{
if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
fprintf(stderr, "%s: PTRACE_TRACEME failed: %m\n", __func__);
raise(SIGKILL);
}
raise(SIGSTOP);

getpid();

exit(0);
}

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

pid = fork();
if (pid == 0)
ptrace_child();
else if (pid < 0)
fprintf(stderr, "%s: fork() failed: %m\n", __func__);

ret = waitpid(pid, &status, WUNTRACED);
if (ret < 0)
fprintf(stderr, "%s: wait() failed: %m\n", __func__);
if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
fprintf(stderr, "%s: expected SIGSTOP, got status:%#x\n", __func__, status);

return pid;
}

static void stop_ptraced_child(int pid)
{
if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) {
fprintf(stderr, "%s: PTRACE_CONT failed: %m\n", __func__);
return;
}

waitpid(pid, NULL, 0);
}

int main(void)
{
int pid, n, status, step_count = 0;

pid = start_ptraced_child();

if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0))
fprintf(stderr, "%s: PTRACE_OLDSETOPTIONS failed: %m\n", __func__);

while (1) {
if (ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
exit(1);

n = waitpid(pid, &status, WUNTRACED);
if (n < 0)
fprintf(stderr, "%s: wait() failed: %m\n", __func__);


if (WIFSTOPPED(status) &&
(WSTOPSIG(status) == (SIGTRAP|0x80))) {
if (!step_count) {
fprintf(stderr, "SYSEMU_SINGLESTEP doesn't singlestep");
exit(1);
}

/* syscall */

break;
} else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) {
/* single step */
step_count++;
} else {
fprintf(stderr, "expected SIGTRAP or (SIGTRAP | 0x80), got status = %d\n", status);
exit(1);
}
step_count++;
}
stop_ptraced_child(pid);

return 0;
}