File tree Expand file tree Collapse file tree 2 files changed +30
-0
lines changed
tools/testing/selftests/x86 Expand file tree Collapse file tree 2 files changed +30
-0
lines changed Original file line number Diff line number Diff line change 49
49
static void check_user_regs (struct pt_regs * regs )
50
50
{
51
51
if (IS_ENABLED (CONFIG_DEBUG_ENTRY )) {
52
+ /*
53
+ * Make sure that the entry code gave us a sensible EFLAGS
54
+ * register. Native because we want to check the actual CPU
55
+ * state, not the interrupt state as imagined by Xen.
56
+ */
57
+ unsigned long flags = native_save_fl ();
58
+ WARN_ON_ONCE (flags & (X86_EFLAGS_AC | X86_EFLAGS_DF |
59
+ X86_EFLAGS_NT ));
60
+
61
+ /* We think we came from user mode. Make sure pt_regs agrees. */
62
+ WARN_ON_ONCE (!user_mode (regs ));
63
+
64
+ /*
65
+ * All entries from user mode (except #DF) should be on the
66
+ * normal thread stack and should have user pt_regs in the
67
+ * correct location.
68
+ */
52
69
WARN_ON_ONCE (!on_thread_stack ());
53
70
WARN_ON_ONCE (regs != task_pt_regs (current ));
54
71
}
@@ -577,6 +594,7 @@ SYSCALL_DEFINE0(ni_syscall)
577
594
bool noinstr idtentry_enter_cond_rcu (struct pt_regs * regs )
578
595
{
579
596
if (user_mode (regs )) {
597
+ check_user_regs (regs );
580
598
enter_from_user_mode ();
581
599
return false;
582
600
}
@@ -710,6 +728,7 @@ void noinstr idtentry_exit_cond_rcu(struct pt_regs *regs, bool rcu_exit)
710
728
*/
711
729
void noinstr idtentry_enter_user (struct pt_regs * regs )
712
730
{
731
+ check_user_regs (regs );
713
732
enter_from_user_mode ();
714
733
}
715
734
Original file line number Diff line number Diff line change @@ -81,5 +81,16 @@ int main(void)
81
81
printf ("[RUN]\tSet NT|AC|TF and issue a syscall\n" );
82
82
do_it (X86_EFLAGS_NT | X86_EFLAGS_AC | X86_EFLAGS_TF );
83
83
84
+ /*
85
+ * Now try DF. This is evil and it's plausible that we will crash
86
+ * glibc, but glibc would have to do something rather surprising
87
+ * for this to happen.
88
+ */
89
+ printf ("[RUN]\tSet DF and issue a syscall\n" );
90
+ do_it (X86_EFLAGS_DF );
91
+
92
+ printf ("[RUN]\tSet TF|DF and issue a syscall\n" );
93
+ do_it (X86_EFLAGS_TF | X86_EFLAGS_DF );
94
+
84
95
return nerrs == 0 ? 0 : 1 ;
85
96
}
You can’t perform that action at this time.
0 commit comments