Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86: Expose thread features in /proc/$PID/status

Applications and loaders can have logic to decide whether to enable
shadow stack. They usually don't report whether shadow stack has been
enabled or not, so there is no way to verify whether an application
actually is protected by shadow stack.

Add two lines in /proc/$PID/status to report enabled and locked features.

Since, this involves referring to arch specific defines in asm/prctl.h,
implement an arch breakout to emit the feature lines.

[Switched to CET, added to commit log]

Co-developed-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Kees Cook <keescook@chromium.org>
Acked-by: Mike Rapoport (IBM) <rppt@kernel.org>
Tested-by: Pengfei Xu <pengfei.xu@intel.com>
Tested-by: John Allen <john.allen@amd.com>
Tested-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/all/20230613001108.3040476-37-rick.p.edgecombe%40intel.com

authored by

Rick Edgecombe and committed by
Dave Hansen
0ee44885 1d62c653

+30
+23
arch/x86/kernel/cpu/proc.c
··· 4 4 #include <linux/string.h> 5 5 #include <linux/seq_file.h> 6 6 #include <linux/cpufreq.h> 7 + #include <asm/prctl.h> 8 + #include <linux/proc_fs.h> 7 9 8 10 #include "cpu.h" 9 11 ··· 177 175 .stop = c_stop, 178 176 .show = show_cpuinfo, 179 177 }; 178 + 179 + #ifdef CONFIG_X86_USER_SHADOW_STACK 180 + static void dump_x86_features(struct seq_file *m, unsigned long features) 181 + { 182 + if (features & ARCH_SHSTK_SHSTK) 183 + seq_puts(m, "shstk "); 184 + if (features & ARCH_SHSTK_WRSS) 185 + seq_puts(m, "wrss "); 186 + } 187 + 188 + void arch_proc_pid_thread_features(struct seq_file *m, struct task_struct *task) 189 + { 190 + seq_puts(m, "x86_Thread_features:\t"); 191 + dump_x86_features(m, task->thread.features); 192 + seq_putc(m, '\n'); 193 + 194 + seq_puts(m, "x86_Thread_features_locked:\t"); 195 + dump_x86_features(m, task->thread.features_locked); 196 + seq_putc(m, '\n'); 197 + } 198 + #endif /* CONFIG_X86_USER_SHADOW_STACK */
+6
fs/proc/array.c
··· 431 431 seq_printf(m, "untag_mask:\t%#lx\n", mm_untag_mask(mm)); 432 432 } 433 433 434 + __weak void arch_proc_pid_thread_features(struct seq_file *m, 435 + struct task_struct *task) 436 + { 437 + } 438 + 434 439 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, 435 440 struct pid *pid, struct task_struct *task) 436 441 { ··· 460 455 task_cpus_allowed(m, task); 461 456 cpuset_task_status_allowed(m, task); 462 457 task_context_switch_counts(m, task); 458 + arch_proc_pid_thread_features(m, task); 463 459 return 0; 464 460 } 465 461
+1
include/linux/proc_fs.h
··· 159 159 #endif /* CONFIG_PROC_PID_ARCH_STATUS */ 160 160 161 161 void arch_report_meminfo(struct seq_file *m); 162 + void arch_proc_pid_thread_features(struct seq_file *m, struct task_struct *task); 162 163 163 164 #else /* CONFIG_PROC_FS */ 164 165