|
| 1 | +From 3b5f7c47389865240a781933324d165897e00abc Mon Sep 17 00:00:00 2001 |
| 2 | +From: Nathan Chancellor <natechancellor@gmail.com> |
| 3 | +Date: Sat, 5 Jan 2019 11:51:39 -0700 |
| 4 | +Subject: [PATCH 1/2] DO-NOT-UPSTREAM: x86: Revert two commits that break the |
| 5 | + build with Clang |
| 6 | + |
| 7 | +* 4a789213c9a5 ("x86 uaccess: Introduce __put_user_goto") |
| 8 | +* a959dc88f9c8 ("Use __put_user_goto in __put_user_size() and unsafe_put_user()") |
| 9 | + |
| 10 | +We've been fortunate enough to get around the asm goto requirement |
| 11 | +introduced in commit e501ce957a78 ("x86: Force asm-goto") until now. |
| 12 | + |
| 13 | +This is not a clean revert because of commit 2a418cf3f5f1 ("x86/uaccess: |
| 14 | +Don't leak the AC flag into __put_user() value evaluation") and commit |
| 15 | +6ae865615fc4 ("x86/uaccess: Dont leak the AC flag into __put_user() |
| 16 | +argument evaluation"). |
| 17 | + |
| 18 | +Link: https://github.com/ClangBuiltLinux/linux/issues/6 |
| 19 | +Signed-off-by: Nathan Chancellor <natechancellor@gmail.com> |
| 20 | +--- |
| 21 | + arch/x86/include/asm/uaccess.h | 80 +++++++++++++++++----------------- |
| 22 | + 1 file changed, 41 insertions(+), 39 deletions(-) |
| 23 | + |
| 24 | +diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h |
| 25 | +index c82abd6e4ca3..5abc7e144e01 100644 |
| 26 | +--- a/arch/x86/include/asm/uaccess.h |
| 27 | ++++ b/arch/x86/include/asm/uaccess.h |
| 28 | +@@ -182,14 +182,19 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) |
| 29 | + |
| 30 | + |
| 31 | + #ifdef CONFIG_X86_32 |
| 32 | +-#define __put_user_goto_u64(x, addr, label) \ |
| 33 | +- asm_volatile_goto("\n" \ |
| 34 | +- "1: movl %%eax,0(%1)\n" \ |
| 35 | +- "2: movl %%edx,4(%1)\n" \ |
| 36 | +- _ASM_EXTABLE_UA(1b, %l2) \ |
| 37 | +- _ASM_EXTABLE_UA(2b, %l2) \ |
| 38 | +- : : "A" (x), "r" (addr) \ |
| 39 | +- : : label) |
| 40 | ++#define __put_user_asm_u64(x, addr, err, errret) \ |
| 41 | ++ asm volatile("\n" \ |
| 42 | ++ "1: movl %%eax,0(%2)\n" \ |
| 43 | ++ "2: movl %%edx,4(%2)\n" \ |
| 44 | ++ "3:" \ |
| 45 | ++ ".section .fixup,\"ax\"\n" \ |
| 46 | ++ "4: movl %3,%0\n" \ |
| 47 | ++ " jmp 3b\n" \ |
| 48 | ++ ".previous\n" \ |
| 49 | ++ _ASM_EXTABLE_UA(1b, 4b) \ |
| 50 | ++ _ASM_EXTABLE_UA(2b, 4b) \ |
| 51 | ++ : "=r" (err) \ |
| 52 | ++ : "A" (x), "r" (addr), "i" (errret), "0" (err)) |
| 53 | + |
| 54 | + #define __put_user_asm_ex_u64(x, addr) \ |
| 55 | + asm volatile("\n" \ |
| 56 | +@@ -204,8 +209,8 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) |
| 57 | + asm volatile("call __put_user_8" : "=a" (__ret_pu) \ |
| 58 | + : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") |
| 59 | + #else |
| 60 | +-#define __put_user_goto_u64(x, ptr, label) \ |
| 61 | +- __put_user_goto(x, ptr, "q", "", "er", label) |
| 62 | ++#define __put_user_asm_u64(x, ptr, retval, errret) \ |
| 63 | ++ __put_user_asm(x, ptr, retval, "q", "", "er", errret) |
| 64 | + #define __put_user_asm_ex_u64(x, addr) \ |
| 65 | + __put_user_asm_ex(x, addr, "q", "", "er") |
| 66 | + #define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu) |
| 67 | +@@ -266,21 +271,22 @@ extern void __put_user_8(void); |
| 68 | + __builtin_expect(__ret_pu, 0); \ |
| 69 | + }) |
| 70 | + |
| 71 | +-#define __put_user_size(x, ptr, size, label) \ |
| 72 | ++#define __put_user_size(x, ptr, size, retval, errret) \ |
| 73 | + do { \ |
| 74 | ++ retval = 0; \ |
| 75 | + __chk_user_ptr(ptr); \ |
| 76 | + switch (size) { \ |
| 77 | + case 1: \ |
| 78 | +- __put_user_goto(x, ptr, "b", "b", "iq", label); \ |
| 79 | ++ __put_user_asm(x, ptr, retval, "b", "b", "iq", errret); \ |
| 80 | + break; \ |
| 81 | + case 2: \ |
| 82 | +- __put_user_goto(x, ptr, "w", "w", "ir", label); \ |
| 83 | ++ __put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \ |
| 84 | + break; \ |
| 85 | + case 4: \ |
| 86 | +- __put_user_goto(x, ptr, "l", "k", "ir", label); \ |
| 87 | ++ __put_user_asm(x, ptr, retval, "l", "k", "ir", errret); \ |
| 88 | + break; \ |
| 89 | + case 8: \ |
| 90 | +- __put_user_goto_u64(x, ptr, label); \ |
| 91 | ++ __put_user_asm_u64(x, ptr, retval, errret); \ |
| 92 | + break; \ |
| 93 | + default: \ |
| 94 | + __put_user_bad(); \ |
| 95 | +@@ -425,15 +431,12 @@ do { \ |
| 96 | + |
| 97 | + #define __put_user_nocheck(x, ptr, size) \ |
| 98 | + ({ \ |
| 99 | +- __label__ __pu_label; \ |
| 100 | +- int __pu_err = -EFAULT; \ |
| 101 | ++ int __pu_err; \ |
| 102 | + __typeof__(*(ptr)) __pu_val = (x); \ |
| 103 | + __typeof__(ptr) __pu_ptr = (ptr); \ |
| 104 | + __typeof__(size) __pu_size = (size); \ |
| 105 | + __uaccess_begin(); \ |
| 106 | +- __put_user_size(__pu_val, __pu_ptr, __pu_size, __pu_label); \ |
| 107 | +- __pu_err = 0; \ |
| 108 | +-__pu_label: \ |
| 109 | ++ __put_user_size(__pu_val, __pu_ptr, __pu_size, __pu_err, -EFAULT);\ |
| 110 | + __uaccess_end(); \ |
| 111 | + __builtin_expect(__pu_err, 0); \ |
| 112 | + }) |
| 113 | +@@ -458,23 +461,17 @@ struct __large_struct { unsigned long buf[100]; }; |
| 114 | + * we do not write to any memory gcc knows about, so there are no |
| 115 | + * aliasing issues. |
| 116 | + */ |
| 117 | +-#define __put_user_goto(x, addr, itype, rtype, ltype, label) \ |
| 118 | +- asm_volatile_goto("\n" \ |
| 119 | +- "1: mov"itype" %"rtype"0,%1\n" \ |
| 120 | +- _ASM_EXTABLE_UA(1b, %l2) \ |
| 121 | +- : : ltype(x), "m" (__m(addr)) \ |
| 122 | +- : : label) |
| 123 | +- |
| 124 | +-#define __put_user_failed(x, addr, itype, rtype, ltype, errret) \ |
| 125 | +- ({ __label__ __puflab; \ |
| 126 | +- int __pufret = errret; \ |
| 127 | +- __put_user_goto(x,addr,itype,rtype,ltype,__puflab); \ |
| 128 | +- __pufret = 0; \ |
| 129 | +- __puflab: __pufret; }) |
| 130 | +- |
| 131 | +-#define __put_user_asm(x, addr, retval, itype, rtype, ltype, errret) do { \ |
| 132 | +- retval = __put_user_failed(x, addr, itype, rtype, ltype, errret); \ |
| 133 | +-} while (0) |
| 134 | ++#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ |
| 135 | ++ asm volatile("\n" \ |
| 136 | ++ "1: mov"itype" %"rtype"1,%2\n" \ |
| 137 | ++ "2:\n" \ |
| 138 | ++ ".section .fixup,\"ax\"\n" \ |
| 139 | ++ "3: mov %3,%0\n" \ |
| 140 | ++ " jmp 2b\n" \ |
| 141 | ++ ".previous\n" \ |
| 142 | ++ _ASM_EXTABLE_UA(1b, 3b) \ |
| 143 | ++ : "=r"(err) \ |
| 144 | ++ : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err)) |
| 145 | + |
| 146 | + #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \ |
| 147 | + asm volatile("1: mov"itype" %"rtype"0,%1\n" \ |
| 148 | +@@ -718,8 +715,13 @@ static __must_check __always_inline bool user_access_begin(const void __user *pt |
| 149 | + #define user_access_save() smap_save() |
| 150 | + #define user_access_restore(x) smap_restore(x) |
| 151 | + |
| 152 | +-#define unsafe_put_user(x, ptr, label) \ |
| 153 | +- __put_user_size((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) |
| 154 | ++#define unsafe_put_user(x, ptr, err_label) \ |
| 155 | ++do { \ |
| 156 | ++ int __pu_err; \ |
| 157 | ++ __typeof__(*(ptr)) __pu_val = (x); \ |
| 158 | ++ __put_user_size(__pu_val, (ptr), sizeof(*(ptr)), __pu_err, -EFAULT); \ |
| 159 | ++ if (unlikely(__pu_err)) goto err_label; \ |
| 160 | ++} while (0) |
| 161 | + |
| 162 | + #define unsafe_get_user(x, ptr, err_label) \ |
| 163 | + do { \ |
| 164 | +-- |
| 165 | +2.21.0 |
| 166 | + |
| 167 | + |
| 168 | +From f272bf78754e6250c2ea118520686c5b873a114c Mon Sep 17 00:00:00 2001 |
| 169 | +From: Nathan Chancellor <natechancellor@gmail.com> |
| 170 | +Date: Tue, 25 Sep 2018 13:32:33 -0700 |
| 171 | +Subject: [PATCH 2/2] DO-NOT-UPSTREAM: x86: Avoid warnings/errors due to lack |
| 172 | + of asm goto |
| 173 | + |
| 174 | +We don't want to see an inordinate amount of warning spam from |
| 175 | +the BPF samples and after reverting commits 4a789213c9a5 ("x86 |
| 176 | +uaccess: Introduce __put_user_goto") and a959dc88f9c8 ("Use |
| 177 | +__put_user_goto in __put_user_size() and unsafe_put_user()"), we |
| 178 | +can successfully compile an x86 kernel with Clang. |
| 179 | + |
| 180 | +This is obviously not a long term solution. LLVM/Clang support for |
| 181 | +asm goto can be tracked at the below link. |
| 182 | + |
| 183 | +Link: https://github.com/ClangBuiltLinux/linux/issues/6 |
| 184 | +Signed-off-by: Nathan Chancellor <natechancellor@gmail.com> |
| 185 | +--- |
| 186 | + arch/x86/Makefile | 9 +++++---- |
| 187 | + arch/x86/boot/compressed/Makefile | 3 +++ |
| 188 | + drivers/firmware/efi/libstub/Makefile | 4 ++++ |
| 189 | + 3 files changed, 12 insertions(+), 4 deletions(-) |
| 190 | + |
| 191 | +diff --git a/arch/x86/Makefile b/arch/x86/Makefile |
| 192 | +index 56e748a7679f..9237af36280b 100644 |
| 193 | +--- a/arch/x86/Makefile |
| 194 | ++++ b/arch/x86/Makefile |
| 195 | +@@ -227,6 +227,11 @@ ifdef CONFIG_RETPOLINE |
| 196 | + endif |
| 197 | + endif |
| 198 | + |
| 199 | ++# Avoid warnings in arch/x86/include/asm/cpufeature.h when building with Clang |
| 200 | ++ifndef CONFIG_CC_HAS_ASM_GOTO |
| 201 | ++ KBUILD_CFLAGS += -D__BPF_TRACING__ |
| 202 | ++endif |
| 203 | ++ |
| 204 | + archscripts: scripts_basic |
| 205 | + $(Q)$(MAKE) $(build)=arch/x86/tools relocs |
| 206 | + |
| 207 | +@@ -297,10 +302,6 @@ vdso_install: |
| 208 | + |
| 209 | + archprepare: checkbin |
| 210 | + checkbin: |
| 211 | +-ifndef CONFIG_CC_HAS_ASM_GOTO |
| 212 | +- @echo Compiler lacks asm-goto support. |
| 213 | +- @exit 1 |
| 214 | +-endif |
| 215 | + ifdef CONFIG_RETPOLINE |
| 216 | + ifeq ($(RETPOLINE_CFLAGS),) |
| 217 | + @echo "You are building kernel with non-retpoline compiler." >&2 |
| 218 | +diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile |
| 219 | +index 6b84afdd7538..c7265084dd78 100644 |
| 220 | +--- a/arch/x86/boot/compressed/Makefile |
| 221 | ++++ b/arch/x86/boot/compressed/Makefile |
| 222 | +@@ -38,6 +38,9 @@ KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector) |
| 223 | + KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) |
| 224 | + KBUILD_CFLAGS += $(call cc-disable-warning, gnu) |
| 225 | + KBUILD_CFLAGS += -Wno-pointer-sign |
| 226 | ++ifndef CONFIG_CC_HAS_ASM_GOTO |
| 227 | ++KBUILD_CFLAGS += -D__BPF_TRACING__ |
| 228 | ++endif |
| 229 | + |
| 230 | + KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ |
| 231 | + GCOV_PROFILE := n |
| 232 | +diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile |
| 233 | +index 0460c7581220..315f43ea5b0c 100644 |
| 234 | +--- a/drivers/firmware/efi/libstub/Makefile |
| 235 | ++++ b/drivers/firmware/efi/libstub/Makefile |
| 236 | +@@ -24,6 +24,10 @@ cflags-$(CONFIG_ARM) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ |
| 237 | + |
| 238 | + cflags-$(CONFIG_EFI_ARMSTUB) += -I$(srctree)/scripts/dtc/libfdt |
| 239 | + |
| 240 | ++ifndef CONFIG_CC_HAS_ASM_GOTO |
| 241 | ++cflags-$(CONFIG_X86) += -D__BPF_TRACING__ |
| 242 | ++endif |
| 243 | ++ |
| 244 | + KBUILD_CFLAGS := $(cflags-y) -DDISABLE_BRANCH_PROFILING \ |
| 245 | + -D__NO_FORTIFY \ |
| 246 | + $(call cc-option,-ffreestanding) \ |
| 247 | +-- |
| 248 | +2.21.0 |
| 249 | + |
0 commit comments