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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'x86_urgent_for_v6.3_rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Borislav Petkov:

- Add a AMX ptrace self test

- Prevent a false-positive warning when retrieving the (invalid)
address of dynamic FPU features in their init state which are not
saved in init_fpstate at all

- Randomize per-CPU entry areas only when KASLR is enabled

* tag 'x86_urgent_for_v6.3_rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
selftests/x86/amx: Add a ptrace test
x86/fpu/xstate: Prevent false-positive warning in __copy_xstate_uabi_buf()
x86/mm: Do not shuffle CPU entry areas without KASLR

+126 -19
+14 -16
arch/x86/kernel/fpu/xstate.c
··· 1118 1118 zerofrom = offsetof(struct xregs_state, extended_state_area); 1119 1119 1120 1120 /* 1121 - * The ptrace buffer is in non-compacted XSAVE format. In 1122 - * non-compacted format disabled features still occupy state space, 1123 - * but there is no state to copy from in the compacted 1124 - * init_fpstate. The gap tracking will zero these states. 1121 + * This 'mask' indicates which states to copy from fpstate. 1122 + * Those extended states that are not present in fpstate are 1123 + * either disabled or initialized: 1124 + * 1125 + * In non-compacted format, disabled features still occupy 1126 + * state space but there is no state to copy from in the 1127 + * compacted init_fpstate. The gap tracking will zero these 1128 + * states. 1129 + * 1130 + * The extended features have an all zeroes init state. Thus, 1131 + * remove them from 'mask' to zero those features in the user 1132 + * buffer instead of retrieving them from init_fpstate. 1125 1133 */ 1126 - mask = fpstate->user_xfeatures; 1127 - 1128 - /* 1129 - * Dynamic features are not present in init_fpstate. When they are 1130 - * in an all zeros init state, remove those from 'mask' to zero 1131 - * those features in the user buffer instead of retrieving them 1132 - * from init_fpstate. 1133 - */ 1134 - if (fpu_state_size_dynamic()) 1135 - mask &= (header.xfeatures | xinit->header.xcomp_bv); 1134 + mask = header.xfeatures; 1136 1135 1137 1136 for_each_extended_xfeature(i, mask) { 1138 1137 /* ··· 1150 1151 pkru.pkru = pkru_val; 1151 1152 membuf_write(&to, &pkru, sizeof(pkru)); 1152 1153 } else { 1153 - copy_feature(header.xfeatures & BIT_ULL(i), &to, 1154 + membuf_write(&to, 1154 1155 __raw_xsave_addr(xsave, i), 1155 - __raw_xsave_addr(xinit, i), 1156 1156 xstate_sizes[i]); 1157 1157 } 1158 1158 /*
+7
arch/x86/mm/cpu_entry_area.c
··· 10 10 #include <asm/fixmap.h> 11 11 #include <asm/desc.h> 12 12 #include <asm/kasan.h> 13 + #include <asm/setup.h> 13 14 14 15 static DEFINE_PER_CPU_PAGE_ALIGNED(struct entry_stack_page, entry_stack_storage); 15 16 ··· 29 28 { 30 29 unsigned int max_cea; 31 30 unsigned int i, j; 31 + 32 + if (!kaslr_enabled()) { 33 + for_each_possible_cpu(i) 34 + per_cpu(_cea_offset, i) = i; 35 + return; 36 + } 32 37 33 38 max_cea = (CPU_ENTRY_AREA_MAP_SIZE - PAGE_SIZE) / CPU_ENTRY_AREA_SIZE; 34 39
+105 -3
tools/testing/selftests/x86/amx.c
··· 14 14 #include <sys/auxv.h> 15 15 #include <sys/mman.h> 16 16 #include <sys/shm.h> 17 + #include <sys/ptrace.h> 17 18 #include <sys/syscall.h> 18 19 #include <sys/wait.h> 20 + #include <sys/uio.h> 19 21 20 22 #include "../kselftest.h" /* For __cpuid_count() */ 21 23 ··· 585 583 _exit(0); 586 584 } 587 585 586 + static inline int __compare_tiledata_state(struct xsave_buffer *xbuf1, struct xsave_buffer *xbuf2) 587 + { 588 + return memcmp(&xbuf1->bytes[xtiledata.xbuf_offset], 589 + &xbuf2->bytes[xtiledata.xbuf_offset], 590 + xtiledata.size); 591 + } 592 + 588 593 /* 589 594 * Save current register state and compare it to @xbuf1.' 590 595 * ··· 608 599 fatal_error("failed to allocate XSAVE buffer\n"); 609 600 610 601 xsave(xbuf2, XFEATURE_MASK_XTILEDATA); 611 - ret = memcmp(&xbuf1->bytes[xtiledata.xbuf_offset], 612 - &xbuf2->bytes[xtiledata.xbuf_offset], 613 - xtiledata.size); 602 + ret = __compare_tiledata_state(xbuf1, xbuf2); 614 603 615 604 free(xbuf2); 616 605 ··· 833 826 free(finfo); 834 827 } 835 828 829 + /* Ptrace test */ 830 + 831 + /* 832 + * Make sure the ptracee has the expanded kernel buffer on the first 833 + * use. Then, initialize the state before performing the state 834 + * injection from the ptracer. 835 + */ 836 + static inline void ptracee_firstuse_tiledata(void) 837 + { 838 + load_rand_tiledata(stashed_xsave); 839 + init_xtiledata(); 840 + } 841 + 842 + /* 843 + * Ptracer injects the randomized tile data state. It also reads 844 + * before and after that, which will execute the kernel's state copy 845 + * functions. So, the tester is advised to double-check any emitted 846 + * kernel messages. 847 + */ 848 + static void ptracer_inject_tiledata(pid_t target) 849 + { 850 + struct xsave_buffer *xbuf; 851 + struct iovec iov; 852 + 853 + xbuf = alloc_xbuf(); 854 + if (!xbuf) 855 + fatal_error("unable to allocate XSAVE buffer"); 856 + 857 + printf("\tRead the init'ed tiledata via ptrace().\n"); 858 + 859 + iov.iov_base = xbuf; 860 + iov.iov_len = xbuf_size; 861 + 862 + memset(stashed_xsave, 0, xbuf_size); 863 + 864 + if (ptrace(PTRACE_GETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov)) 865 + fatal_error("PTRACE_GETREGSET"); 866 + 867 + if (!__compare_tiledata_state(stashed_xsave, xbuf)) 868 + printf("[OK]\tThe init'ed tiledata was read from ptracee.\n"); 869 + else 870 + printf("[FAIL]\tThe init'ed tiledata was not read from ptracee.\n"); 871 + 872 + printf("\tInject tiledata via ptrace().\n"); 873 + 874 + load_rand_tiledata(xbuf); 875 + 876 + memcpy(&stashed_xsave->bytes[xtiledata.xbuf_offset], 877 + &xbuf->bytes[xtiledata.xbuf_offset], 878 + xtiledata.size); 879 + 880 + if (ptrace(PTRACE_SETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov)) 881 + fatal_error("PTRACE_SETREGSET"); 882 + 883 + if (ptrace(PTRACE_GETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov)) 884 + fatal_error("PTRACE_GETREGSET"); 885 + 886 + if (!__compare_tiledata_state(stashed_xsave, xbuf)) 887 + printf("[OK]\tTiledata was correctly written to ptracee.\n"); 888 + else 889 + printf("[FAIL]\tTiledata was not correctly written to ptracee.\n"); 890 + } 891 + 892 + static void test_ptrace(void) 893 + { 894 + pid_t child; 895 + int status; 896 + 897 + child = fork(); 898 + if (child < 0) { 899 + err(1, "fork"); 900 + } else if (!child) { 901 + if (ptrace(PTRACE_TRACEME, 0, NULL, NULL)) 902 + err(1, "PTRACE_TRACEME"); 903 + 904 + ptracee_firstuse_tiledata(); 905 + 906 + raise(SIGTRAP); 907 + _exit(0); 908 + } 909 + 910 + do { 911 + wait(&status); 912 + } while (WSTOPSIG(status) != SIGTRAP); 913 + 914 + ptracer_inject_tiledata(child); 915 + 916 + ptrace(PTRACE_DETACH, child, NULL, NULL); 917 + wait(&status); 918 + if (!WIFEXITED(status) || WEXITSTATUS(status)) 919 + err(1, "ptrace test"); 920 + } 921 + 836 922 int main(void) 837 923 { 838 924 /* Check hardware availability at first */ ··· 945 845 ctxtswtest_config.iterations = 10; 946 846 ctxtswtest_config.num_threads = 5; 947 847 test_context_switch(); 848 + 849 + test_ptrace(); 948 850 949 851 clearhandler(SIGILL); 950 852 free_stashed_xsave();