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;
}