From: Andrea Arcangeli Make the TSC disable purely paranoid feature optional, so by default seccomp returns absolutely zerocost. Signed-off-by: Andrea Arcangeli Signed-off-by: Andrew Morton --- arch/i386/Kconfig | 12 ++++++++++++ arch/i386/kernel/process.c | 2 ++ arch/x86_64/Kconfig | 12 ++++++++++++ arch/x86_64/kernel/process.c | 31 +++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+) diff -puN arch/i386/Kconfig~add-seccomp_disable_tsc-config-option arch/i386/Kconfig --- a/arch/i386/Kconfig~add-seccomp_disable_tsc-config-option +++ a/arch/i386/Kconfig @@ -734,6 +734,18 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. +config SECCOMP_DISABLE_TSC + bool "Disable the TSC for seccomp tasks" + depends on SECCOMP + default n + help + This feature mathematically prevents covert channels + for tasks running under SECCOMP. This can generate + a minuscule overhead in the scheduler. + + If you care most about performance say N. Say Y only if you're + paranoid about covert channels. + config VGA_NOPROBE bool "Don't probe VGA at boot" if EMBEDDED default n diff -puN arch/i386/kernel/process.c~add-seccomp_disable_tsc-config-option arch/i386/kernel/process.c --- a/arch/i386/kernel/process.c~add-seccomp_disable_tsc-config-option +++ a/arch/i386/kernel/process.c @@ -590,6 +590,7 @@ static noinline void __switch_to_xtra(st static inline void disable_tsc(struct task_struct *prev_p, struct task_struct *next_p) { +#ifdef CONFIG_SECCOMP_DISABLE_TSC struct thread_info *prev, *next; /* @@ -608,6 +609,7 @@ static inline void disable_tsc(struct ta has_secure_computing(next)) write_cr4(read_cr4() | X86_CR4_TSD); } +#endif } /* diff -puN arch/x86_64/Kconfig~add-seccomp_disable_tsc-config-option arch/x86_64/Kconfig --- a/arch/x86_64/Kconfig~add-seccomp_disable_tsc-config-option +++ a/arch/x86_64/Kconfig @@ -567,6 +567,18 @@ config CC_STACKPROTECTOR_ALL functions that use large-ish on-stack buffers. By enabling this option, GCC will be asked to do this for ALL functions. +config SECCOMP_DISABLE_TSC + bool "Disable the TSC for seccomp tasks" + depends on SECCOMP + default n + help + This feature mathematically prevents covert channels + for tasks running under SECCOMP. This can generate + a minuscule overhead in the scheduler. + + If you care most about performance say N. Say Y only if you're + paranoid about covert channels. + source kernel/Kconfig.hz config REORDER diff -puN arch/x86_64/kernel/process.c~add-seccomp_disable_tsc-config-option arch/x86_64/kernel/process.c --- a/arch/x86_64/kernel/process.c~add-seccomp_disable_tsc-config-option +++ a/arch/x86_64/kernel/process.c @@ -508,6 +508,35 @@ out: } /* + * This function selects if the context switch from prev to next + * has to tweak the TSC disable bit in the cr4. + */ +static inline void disable_tsc(struct task_struct *prev_p, + struct task_struct *next_p) +{ +#ifdef CONFIG_SECCOMP_DISABLE_TSC + struct thread_info *prev, *next; + + /* + * gcc should eliminate the ->thread_info dereference if + * has_secure_computing returns 0 at compile time (SECCOMP=n). + */ + prev = prev_p->thread_info; + next = next_p->thread_info; + + if (has_secure_computing(prev) || has_secure_computing(next)) { + /* slow path here */ + if (has_secure_computing(prev) && + !has_secure_computing(next)) { + write_cr4(read_cr4() & ~X86_CR4_TSD); + } else if (!has_secure_computing(prev) && + has_secure_computing(next)) + write_cr4((read_cr4() | X86_CR4_TSD) & ~X86_CR4_PCE); + } +#endif +} + +/* * This special macro can be used to load a debugging register */ #define loaddebug(thread,r) set_debugreg(thread->debugreg ## r, r) @@ -652,6 +681,8 @@ __switch_to(struct task_struct *prev_p, || test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) __switch_to_xtra(prev_p, next_p, tss); + disable_tsc(prev_p, next_p); + /* If the task has used fpu the last 5 timeslices, just do a full * restore of the math state immediately to avoid the trap; the * chances of needing FPU soon are obviously high now _