File Index
Files and directories
Sign in
FILE

syscall_nt.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/x86/syscall_nt.c C
 1// SPDX-License-Identifier: GPL-2.0-only
 2/*
 3 * syscall_nt.c - checks syscalls with NT set
 4 * Copyright (c) 2014-2015 Andrew Lutomirski
 5 *
 6 * Some obscure user-space code requires the ability to make system calls
 7 * with FLAGS.NT set.  Make sure it works.
 8 */
 9
10#include <stdio.h>
11#include <unistd.h>
12#include <string.h>
13#include <signal.h>
14#include <err.h>
15#include <sys/syscall.h>
16
17#include "helpers.h"
18
19static unsigned int nerrs;
20
21static void sigtrap(int sig, siginfo_t *si, void *ctx_void)
22{
23}
24
25static void do_it(unsigned long extraflags)
26{
27	unsigned long flags;
28
29	set_eflags(get_eflags() | extraflags);
30	syscall(SYS_getpid);
31	flags = get_eflags();
32	set_eflags(X86_EFLAGS_IF | X86_EFLAGS_FIXED);
33	if ((flags & extraflags) == extraflags) {
34		printf("[OK]\tThe syscall worked and flags are still set\n");
35	} else {
36		printf("[FAIL]\tThe syscall worked but flags were cleared (flags = 0x%lx but expected 0x%lx set)\n",
37		       flags, extraflags);
38		nerrs++;
39	}
40}
41
42int main(void)
43{
44	printf("[RUN]\tSet NT and issue a syscall\n");
45	do_it(X86_EFLAGS_NT);
46
47	printf("[RUN]\tSet AC and issue a syscall\n");
48	do_it(X86_EFLAGS_AC);
49
50	printf("[RUN]\tSet NT|AC and issue a syscall\n");
51	do_it(X86_EFLAGS_NT | X86_EFLAGS_AC);
52
53	/*
54	 * Now try it again with TF set -- TF forces returns via IRET in all
55	 * cases except non-ptregs-using 64-bit full fast path syscalls.
56	 */
57
58	sethandler(SIGTRAP, sigtrap, 0);
59
60	printf("[RUN]\tSet TF and issue a syscall\n");
61	do_it(X86_EFLAGS_TF);
62
63	printf("[RUN]\tSet NT|TF and issue a syscall\n");
64	do_it(X86_EFLAGS_NT | X86_EFLAGS_TF);
65
66	printf("[RUN]\tSet AC|TF and issue a syscall\n");
67	do_it(X86_EFLAGS_AC | X86_EFLAGS_TF);
68
69	printf("[RUN]\tSet NT|AC|TF and issue a syscall\n");
70	do_it(X86_EFLAGS_NT | X86_EFLAGS_AC | X86_EFLAGS_TF);
71
72	/*
73	 * Now try DF.  This is evil and it's plausible that we will crash
74	 * glibc, but glibc would have to do something rather surprising
75	 * for this to happen.
76	 */
77	printf("[RUN]\tSet DF and issue a syscall\n");
78	do_it(X86_EFLAGS_DF);
79
80	printf("[RUN]\tSet TF|DF and issue a syscall\n");
81	do_it(X86_EFLAGS_TF | X86_EFLAGS_DF);
82
83	return nerrs == 0 ? 0 : 1;
84}
~/ Read-only file preview.