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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux ia64]     [Linux Kernel]     [DCCP]     [Linux ARM]     [Yosemite News]     [Linux SCSI]     [Linux Hams]
  Powered by Linux