Annotation of /trunk/kernel-alx/patches-4.14/0125-4.14.26-all-fixes.patch
Parent Directory | Revision Log
Revision 3238 -
(hide annotations)
(download)
Fri Nov 9 12:14:58 2018 UTC (5 years, 10 months ago) by niro
File size: 19823 byte(s)
Fri Nov 9 12:14:58 2018 UTC (5 years, 10 months ago) by niro
File size: 19823 byte(s)
-added up to patches-4.14.79
1 | niro | 3238 | diff --git a/Documentation/virtual/kvm/cpuid.txt b/Documentation/virtual/kvm/cpuid.txt |
2 | index 3c65feb83010..a81c97a4b4a5 100644 | ||
3 | --- a/Documentation/virtual/kvm/cpuid.txt | ||
4 | +++ b/Documentation/virtual/kvm/cpuid.txt | ||
5 | @@ -54,6 +54,10 @@ KVM_FEATURE_PV_UNHALT || 7 || guest checks this feature bit | ||
6 | || || before enabling paravirtualized | ||
7 | || || spinlock support. | ||
8 | ------------------------------------------------------------------------------ | ||
9 | +KVM_FEATURE_ASYNC_PF_VMEXIT || 10 || paravirtualized async PF VM exit | ||
10 | + || || can be enabled by setting bit 2 | ||
11 | + || || when writing to msr 0x4b564d02 | ||
12 | +------------------------------------------------------------------------------ | ||
13 | KVM_FEATURE_CLOCKSOURCE_STABLE_BIT || 24 || host will warn if no guest-side | ||
14 | || || per-cpu warps are expected in | ||
15 | || || kvmclock. | ||
16 | diff --git a/Documentation/virtual/kvm/msr.txt b/Documentation/virtual/kvm/msr.txt | ||
17 | index 1ebecc115dc6..f3f0d57ced8e 100644 | ||
18 | --- a/Documentation/virtual/kvm/msr.txt | ||
19 | +++ b/Documentation/virtual/kvm/msr.txt | ||
20 | @@ -170,7 +170,8 @@ MSR_KVM_ASYNC_PF_EN: 0x4b564d02 | ||
21 | when asynchronous page faults are enabled on the vcpu 0 when | ||
22 | disabled. Bit 1 is 1 if asynchronous page faults can be injected | ||
23 | when vcpu is in cpl == 0. Bit 2 is 1 if asynchronous page faults | ||
24 | - are delivered to L1 as #PF vmexits. | ||
25 | + are delivered to L1 as #PF vmexits. Bit 2 can be set only if | ||
26 | + KVM_FEATURE_ASYNC_PF_VMEXIT is present in CPUID. | ||
27 | |||
28 | First 4 byte of 64 byte memory location will be written to by | ||
29 | the hypervisor at the time of asynchronous page fault (APF) | ||
30 | diff --git a/Makefile b/Makefile | ||
31 | index 0fdae0f455ef..666182dda187 100644 | ||
32 | --- a/Makefile | ||
33 | +++ b/Makefile | ||
34 | @@ -1,7 +1,7 @@ | ||
35 | # SPDX-License-Identifier: GPL-2.0 | ||
36 | VERSION = 4 | ||
37 | PATCHLEVEL = 14 | ||
38 | -SUBLEVEL = 25 | ||
39 | +SUBLEVEL = 26 | ||
40 | EXTRAVERSION = | ||
41 | NAME = Petit Gorille | ||
42 | |||
43 | diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c | ||
44 | index bb32f7f6dd0f..be155f70f108 100644 | ||
45 | --- a/arch/arm64/net/bpf_jit_comp.c | ||
46 | +++ b/arch/arm64/net/bpf_jit_comp.c | ||
47 | @@ -238,8 +238,9 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx) | ||
48 | off = offsetof(struct bpf_array, map.max_entries); | ||
49 | emit_a64_mov_i64(tmp, off, ctx); | ||
50 | emit(A64_LDR32(tmp, r2, tmp), ctx); | ||
51 | + emit(A64_MOV(0, r3, r3), ctx); | ||
52 | emit(A64_CMP(0, r3, tmp), ctx); | ||
53 | - emit(A64_B_(A64_COND_GE, jmp_offset), ctx); | ||
54 | + emit(A64_B_(A64_COND_CS, jmp_offset), ctx); | ||
55 | |||
56 | /* if (tail_call_cnt > MAX_TAIL_CALL_CNT) | ||
57 | * goto out; | ||
58 | @@ -247,7 +248,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx) | ||
59 | */ | ||
60 | emit_a64_mov_i64(tmp, MAX_TAIL_CALL_CNT, ctx); | ||
61 | emit(A64_CMP(1, tcc, tmp), ctx); | ||
62 | - emit(A64_B_(A64_COND_GT, jmp_offset), ctx); | ||
63 | + emit(A64_B_(A64_COND_HI, jmp_offset), ctx); | ||
64 | emit(A64_ADD_I(1, tcc, tcc, 1), ctx); | ||
65 | |||
66 | /* prog = array->ptrs[index]; | ||
67 | diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c | ||
68 | index 5d115bd32539..bd0786c23109 100644 | ||
69 | --- a/arch/powerpc/net/bpf_jit_comp64.c | ||
70 | +++ b/arch/powerpc/net/bpf_jit_comp64.c | ||
71 | @@ -241,6 +241,7 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 | ||
72 | * goto out; | ||
73 | */ | ||
74 | PPC_LWZ(b2p[TMP_REG_1], b2p_bpf_array, offsetof(struct bpf_array, map.max_entries)); | ||
75 | + PPC_RLWINM(b2p_index, b2p_index, 0, 0, 31); | ||
76 | PPC_CMPLW(b2p_index, b2p[TMP_REG_1]); | ||
77 | PPC_BCC(COND_GE, out); | ||
78 | |||
79 | diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h | ||
80 | index 76b058533e47..81a1be326571 100644 | ||
81 | --- a/arch/x86/include/asm/nospec-branch.h | ||
82 | +++ b/arch/x86/include/asm/nospec-branch.h | ||
83 | @@ -177,4 +177,41 @@ static inline void indirect_branch_prediction_barrier(void) | ||
84 | } | ||
85 | |||
86 | #endif /* __ASSEMBLY__ */ | ||
87 | + | ||
88 | +/* | ||
89 | + * Below is used in the eBPF JIT compiler and emits the byte sequence | ||
90 | + * for the following assembly: | ||
91 | + * | ||
92 | + * With retpolines configured: | ||
93 | + * | ||
94 | + * callq do_rop | ||
95 | + * spec_trap: | ||
96 | + * pause | ||
97 | + * lfence | ||
98 | + * jmp spec_trap | ||
99 | + * do_rop: | ||
100 | + * mov %rax,(%rsp) | ||
101 | + * retq | ||
102 | + * | ||
103 | + * Without retpolines configured: | ||
104 | + * | ||
105 | + * jmp *%rax | ||
106 | + */ | ||
107 | +#ifdef CONFIG_RETPOLINE | ||
108 | +# define RETPOLINE_RAX_BPF_JIT_SIZE 17 | ||
109 | +# define RETPOLINE_RAX_BPF_JIT() \ | ||
110 | + EMIT1_off32(0xE8, 7); /* callq do_rop */ \ | ||
111 | + /* spec_trap: */ \ | ||
112 | + EMIT2(0xF3, 0x90); /* pause */ \ | ||
113 | + EMIT3(0x0F, 0xAE, 0xE8); /* lfence */ \ | ||
114 | + EMIT2(0xEB, 0xF9); /* jmp spec_trap */ \ | ||
115 | + /* do_rop: */ \ | ||
116 | + EMIT4(0x48, 0x89, 0x04, 0x24); /* mov %rax,(%rsp) */ \ | ||
117 | + EMIT1(0xC3); /* retq */ | ||
118 | +#else | ||
119 | +# define RETPOLINE_RAX_BPF_JIT_SIZE 2 | ||
120 | +# define RETPOLINE_RAX_BPF_JIT() \ | ||
121 | + EMIT2(0xFF, 0xE0); /* jmp *%rax */ | ||
122 | +#endif | ||
123 | + | ||
124 | #endif /* _ASM_X86_NOSPEC_BRANCH_H_ */ | ||
125 | diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h | ||
126 | index 554aa8f24f91..341db0462b85 100644 | ||
127 | --- a/arch/x86/include/uapi/asm/kvm_para.h | ||
128 | +++ b/arch/x86/include/uapi/asm/kvm_para.h | ||
129 | @@ -25,6 +25,7 @@ | ||
130 | #define KVM_FEATURE_STEAL_TIME 5 | ||
131 | #define KVM_FEATURE_PV_EOI 6 | ||
132 | #define KVM_FEATURE_PV_UNHALT 7 | ||
133 | +#define KVM_FEATURE_ASYNC_PF_VMEXIT 10 | ||
134 | |||
135 | /* The last 8 bits are used to indicate how to interpret the flags field | ||
136 | * in pvclock structure. If no bits are set, all flags are ignored. | ||
137 | diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c | ||
138 | index a94de09edbed..652bdd867782 100644 | ||
139 | --- a/arch/x86/kernel/kvm.c | ||
140 | +++ b/arch/x86/kernel/kvm.c | ||
141 | @@ -341,10 +341,10 @@ static void kvm_guest_cpu_init(void) | ||
142 | #endif | ||
143 | pa |= KVM_ASYNC_PF_ENABLED; | ||
144 | |||
145 | - /* Async page fault support for L1 hypervisor is optional */ | ||
146 | - if (wrmsr_safe(MSR_KVM_ASYNC_PF_EN, | ||
147 | - (pa | KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT) & 0xffffffff, pa >> 32) < 0) | ||
148 | - wrmsrl(MSR_KVM_ASYNC_PF_EN, pa); | ||
149 | + if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF_VMEXIT)) | ||
150 | + pa |= KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT; | ||
151 | + | ||
152 | + wrmsrl(MSR_KVM_ASYNC_PF_EN, pa); | ||
153 | __this_cpu_write(apf_reason.enabled, 1); | ||
154 | printk(KERN_INFO"KVM setup async PF for cpu %d\n", | ||
155 | smp_processor_id()); | ||
156 | diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c | ||
157 | index 13f5d4217e4f..4f544f2a7b06 100644 | ||
158 | --- a/arch/x86/kvm/cpuid.c | ||
159 | +++ b/arch/x86/kvm/cpuid.c | ||
160 | @@ -597,7 +597,8 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | ||
161 | (1 << KVM_FEATURE_ASYNC_PF) | | ||
162 | (1 << KVM_FEATURE_PV_EOI) | | ||
163 | (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) | | ||
164 | - (1 << KVM_FEATURE_PV_UNHALT); | ||
165 | + (1 << KVM_FEATURE_PV_UNHALT) | | ||
166 | + (1 << KVM_FEATURE_ASYNC_PF_VMEXIT); | ||
167 | |||
168 | if (sched_info_on()) | ||
169 | entry->eax |= (1 << KVM_FEATURE_STEAL_TIME); | ||
170 | diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c | ||
171 | index 0554e8aef4d5..940aac70b4da 100644 | ||
172 | --- a/arch/x86/net/bpf_jit_comp.c | ||
173 | +++ b/arch/x86/net/bpf_jit_comp.c | ||
174 | @@ -13,6 +13,7 @@ | ||
175 | #include <linux/if_vlan.h> | ||
176 | #include <asm/cacheflush.h> | ||
177 | #include <asm/set_memory.h> | ||
178 | +#include <asm/nospec-branch.h> | ||
179 | #include <linux/bpf.h> | ||
180 | |||
181 | int bpf_jit_enable __read_mostly; | ||
182 | @@ -287,7 +288,7 @@ static void emit_bpf_tail_call(u8 **pprog) | ||
183 | EMIT2(0x89, 0xD2); /* mov edx, edx */ | ||
184 | EMIT3(0x39, 0x56, /* cmp dword ptr [rsi + 16], edx */ | ||
185 | offsetof(struct bpf_array, map.max_entries)); | ||
186 | -#define OFFSET1 43 /* number of bytes to jump */ | ||
187 | +#define OFFSET1 (41 + RETPOLINE_RAX_BPF_JIT_SIZE) /* number of bytes to jump */ | ||
188 | EMIT2(X86_JBE, OFFSET1); /* jbe out */ | ||
189 | label1 = cnt; | ||
190 | |||
191 | @@ -296,7 +297,7 @@ static void emit_bpf_tail_call(u8 **pprog) | ||
192 | */ | ||
193 | EMIT2_off32(0x8B, 0x85, 36); /* mov eax, dword ptr [rbp + 36] */ | ||
194 | EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */ | ||
195 | -#define OFFSET2 32 | ||
196 | +#define OFFSET2 (30 + RETPOLINE_RAX_BPF_JIT_SIZE) | ||
197 | EMIT2(X86_JA, OFFSET2); /* ja out */ | ||
198 | label2 = cnt; | ||
199 | EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */ | ||
200 | @@ -310,7 +311,7 @@ static void emit_bpf_tail_call(u8 **pprog) | ||
201 | * goto out; | ||
202 | */ | ||
203 | EMIT3(0x48, 0x85, 0xC0); /* test rax,rax */ | ||
204 | -#define OFFSET3 10 | ||
205 | +#define OFFSET3 (8 + RETPOLINE_RAX_BPF_JIT_SIZE) | ||
206 | EMIT2(X86_JE, OFFSET3); /* je out */ | ||
207 | label3 = cnt; | ||
208 | |||
209 | @@ -323,7 +324,7 @@ static void emit_bpf_tail_call(u8 **pprog) | ||
210 | * rdi == ctx (1st arg) | ||
211 | * rax == prog->bpf_func + prologue_size | ||
212 | */ | ||
213 | - EMIT2(0xFF, 0xE0); /* jmp rax */ | ||
214 | + RETPOLINE_RAX_BPF_JIT(); | ||
215 | |||
216 | /* out: */ | ||
217 | BUILD_BUG_ON(cnt - label1 != OFFSET1); | ||
218 | diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c | ||
219 | index a4ae1ca44a57..f57d0bdf3c9e 100644 | ||
220 | --- a/kernel/bpf/arraymap.c | ||
221 | +++ b/kernel/bpf/arraymap.c | ||
222 | @@ -23,8 +23,10 @@ static void bpf_array_free_percpu(struct bpf_array *array) | ||
223 | { | ||
224 | int i; | ||
225 | |||
226 | - for (i = 0; i < array->map.max_entries; i++) | ||
227 | + for (i = 0; i < array->map.max_entries; i++) { | ||
228 | free_percpu(array->pptrs[i]); | ||
229 | + cond_resched(); | ||
230 | + } | ||
231 | } | ||
232 | |||
233 | static int bpf_array_alloc_percpu(struct bpf_array *array) | ||
234 | @@ -40,6 +42,7 @@ static int bpf_array_alloc_percpu(struct bpf_array *array) | ||
235 | return -ENOMEM; | ||
236 | } | ||
237 | array->pptrs[i] = ptr; | ||
238 | + cond_resched(); | ||
239 | } | ||
240 | |||
241 | return 0; | ||
242 | @@ -49,11 +52,11 @@ static int bpf_array_alloc_percpu(struct bpf_array *array) | ||
243 | static struct bpf_map *array_map_alloc(union bpf_attr *attr) | ||
244 | { | ||
245 | bool percpu = attr->map_type == BPF_MAP_TYPE_PERCPU_ARRAY; | ||
246 | - int numa_node = bpf_map_attr_numa_node(attr); | ||
247 | + int ret, numa_node = bpf_map_attr_numa_node(attr); | ||
248 | u32 elem_size, index_mask, max_entries; | ||
249 | bool unpriv = !capable(CAP_SYS_ADMIN); | ||
250 | + u64 cost, array_size, mask64; | ||
251 | struct bpf_array *array; | ||
252 | - u64 array_size, mask64; | ||
253 | |||
254 | /* check sanity of attributes */ | ||
255 | if (attr->max_entries == 0 || attr->key_size != 4 || | ||
256 | @@ -97,8 +100,19 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) | ||
257 | array_size += (u64) max_entries * elem_size; | ||
258 | |||
259 | /* make sure there is no u32 overflow later in round_up() */ | ||
260 | - if (array_size >= U32_MAX - PAGE_SIZE) | ||
261 | + cost = array_size; | ||
262 | + if (cost >= U32_MAX - PAGE_SIZE) | ||
263 | return ERR_PTR(-ENOMEM); | ||
264 | + if (percpu) { | ||
265 | + cost += (u64)attr->max_entries * elem_size * num_possible_cpus(); | ||
266 | + if (cost >= U32_MAX - PAGE_SIZE) | ||
267 | + return ERR_PTR(-ENOMEM); | ||
268 | + } | ||
269 | + cost = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT; | ||
270 | + | ||
271 | + ret = bpf_map_precharge_memlock(cost); | ||
272 | + if (ret < 0) | ||
273 | + return ERR_PTR(ret); | ||
274 | |||
275 | /* allocate all map elements and zero-initialize them */ | ||
276 | array = bpf_map_area_alloc(array_size, numa_node); | ||
277 | @@ -114,20 +128,13 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) | ||
278 | array->map.max_entries = attr->max_entries; | ||
279 | array->map.map_flags = attr->map_flags; | ||
280 | array->map.numa_node = numa_node; | ||
281 | + array->map.pages = cost; | ||
282 | array->elem_size = elem_size; | ||
283 | |||
284 | - if (!percpu) | ||
285 | - goto out; | ||
286 | - | ||
287 | - array_size += (u64) attr->max_entries * elem_size * num_possible_cpus(); | ||
288 | - | ||
289 | - if (array_size >= U32_MAX - PAGE_SIZE || | ||
290 | - bpf_array_alloc_percpu(array)) { | ||
291 | + if (percpu && bpf_array_alloc_percpu(array)) { | ||
292 | bpf_map_area_free(array); | ||
293 | return ERR_PTR(-ENOMEM); | ||
294 | } | ||
295 | -out: | ||
296 | - array->map.pages = round_up(array_size, PAGE_SIZE) >> PAGE_SHIFT; | ||
297 | |||
298 | return &array->map; | ||
299 | } | ||
300 | diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c | ||
301 | index 1b767844a76f..c28c584b734e 100644 | ||
302 | --- a/kernel/bpf/lpm_trie.c | ||
303 | +++ b/kernel/bpf/lpm_trie.c | ||
304 | @@ -470,7 +470,10 @@ static void trie_free(struct bpf_map *map) | ||
305 | struct lpm_trie_node __rcu **slot; | ||
306 | struct lpm_trie_node *node; | ||
307 | |||
308 | - raw_spin_lock(&trie->lock); | ||
309 | + /* Wait for outstanding programs to complete | ||
310 | + * update/lookup/delete/get_next_key and free the trie. | ||
311 | + */ | ||
312 | + synchronize_rcu(); | ||
313 | |||
314 | /* Always start at the root and walk down to a node that has no | ||
315 | * children. Then free that node, nullify its reference in the parent | ||
316 | @@ -481,10 +484,9 @@ static void trie_free(struct bpf_map *map) | ||
317 | slot = &trie->root; | ||
318 | |||
319 | for (;;) { | ||
320 | - node = rcu_dereference_protected(*slot, | ||
321 | - lockdep_is_held(&trie->lock)); | ||
322 | + node = rcu_dereference_protected(*slot, 1); | ||
323 | if (!node) | ||
324 | - goto unlock; | ||
325 | + goto out; | ||
326 | |||
327 | if (rcu_access_pointer(node->child[0])) { | ||
328 | slot = &node->child[0]; | ||
329 | @@ -502,8 +504,8 @@ static void trie_free(struct bpf_map *map) | ||
330 | } | ||
331 | } | ||
332 | |||
333 | -unlock: | ||
334 | - raw_spin_unlock(&trie->lock); | ||
335 | +out: | ||
336 | + kfree(trie); | ||
337 | } | ||
338 | |||
339 | static int trie_get_next_key(struct bpf_map *map, void *key, void *next_key) | ||
340 | diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c | ||
341 | index b5ae6488b890..3ceb269c0ebd 100644 | ||
342 | --- a/kernel/bpf/verifier.c | ||
343 | +++ b/kernel/bpf/verifier.c | ||
344 | @@ -993,6 +993,13 @@ static bool is_ctx_reg(struct bpf_verifier_env *env, int regno) | ||
345 | return reg->type == PTR_TO_CTX; | ||
346 | } | ||
347 | |||
348 | +static bool is_pkt_reg(struct bpf_verifier_env *env, int regno) | ||
349 | +{ | ||
350 | + const struct bpf_reg_state *reg = &env->cur_state.regs[regno]; | ||
351 | + | ||
352 | + return reg->type == PTR_TO_PACKET; | ||
353 | +} | ||
354 | + | ||
355 | static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg, | ||
356 | int off, int size, bool strict) | ||
357 | { | ||
358 | @@ -1050,10 +1057,10 @@ static int check_generic_ptr_alignment(const struct bpf_reg_state *reg, | ||
359 | } | ||
360 | |||
361 | static int check_ptr_alignment(struct bpf_verifier_env *env, | ||
362 | - const struct bpf_reg_state *reg, | ||
363 | - int off, int size) | ||
364 | + const struct bpf_reg_state *reg, int off, | ||
365 | + int size, bool strict_alignment_once) | ||
366 | { | ||
367 | - bool strict = env->strict_alignment; | ||
368 | + bool strict = env->strict_alignment || strict_alignment_once; | ||
369 | const char *pointer_desc = ""; | ||
370 | |||
371 | switch (reg->type) { | ||
372 | @@ -1109,9 +1116,9 @@ static void coerce_reg_to_size(struct bpf_reg_state *reg, int size) | ||
373 | * if t==write && value_regno==-1, some unknown value is stored into memory | ||
374 | * if t==read && value_regno==-1, don't care what we read from memory | ||
375 | */ | ||
376 | -static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regno, int off, | ||
377 | - int bpf_size, enum bpf_access_type t, | ||
378 | - int value_regno) | ||
379 | +static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regno, | ||
380 | + int off, int bpf_size, enum bpf_access_type t, | ||
381 | + int value_regno, bool strict_alignment_once) | ||
382 | { | ||
383 | struct bpf_verifier_state *state = &env->cur_state; | ||
384 | struct bpf_reg_state *reg = &state->regs[regno]; | ||
385 | @@ -1122,7 +1129,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn | ||
386 | return size; | ||
387 | |||
388 | /* alignment checks will add in reg->off themselves */ | ||
389 | - err = check_ptr_alignment(env, reg, off, size); | ||
390 | + err = check_ptr_alignment(env, reg, off, size, strict_alignment_once); | ||
391 | if (err) | ||
392 | return err; | ||
393 | |||
394 | @@ -1265,21 +1272,23 @@ static int check_xadd(struct bpf_verifier_env *env, int insn_idx, struct bpf_ins | ||
395 | return -EACCES; | ||
396 | } | ||
397 | |||
398 | - if (is_ctx_reg(env, insn->dst_reg)) { | ||
399 | - verbose("BPF_XADD stores into R%d context is not allowed\n", | ||
400 | - insn->dst_reg); | ||
401 | + if (is_ctx_reg(env, insn->dst_reg) || | ||
402 | + is_pkt_reg(env, insn->dst_reg)) { | ||
403 | + verbose("BPF_XADD stores into R%d %s is not allowed\n", | ||
404 | + insn->dst_reg, is_ctx_reg(env, insn->dst_reg) ? | ||
405 | + "context" : "packet"); | ||
406 | return -EACCES; | ||
407 | } | ||
408 | |||
409 | /* check whether atomic_add can read the memory */ | ||
410 | err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, | ||
411 | - BPF_SIZE(insn->code), BPF_READ, -1); | ||
412 | + BPF_SIZE(insn->code), BPF_READ, -1, true); | ||
413 | if (err) | ||
414 | return err; | ||
415 | |||
416 | /* check whether atomic_add can write into the same memory */ | ||
417 | return check_mem_access(env, insn_idx, insn->dst_reg, insn->off, | ||
418 | - BPF_SIZE(insn->code), BPF_WRITE, -1); | ||
419 | + BPF_SIZE(insn->code), BPF_WRITE, -1, true); | ||
420 | } | ||
421 | |||
422 | /* Does this register contain a constant zero? */ | ||
423 | @@ -1735,7 +1744,8 @@ static int check_call(struct bpf_verifier_env *env, int func_id, int insn_idx) | ||
424 | * is inferred from register state. | ||
425 | */ | ||
426 | for (i = 0; i < meta.access_size; i++) { | ||
427 | - err = check_mem_access(env, insn_idx, meta.regno, i, BPF_B, BPF_WRITE, -1); | ||
428 | + err = check_mem_access(env, insn_idx, meta.regno, i, BPF_B, | ||
429 | + BPF_WRITE, -1, false); | ||
430 | if (err) | ||
431 | return err; | ||
432 | } | ||
433 | @@ -3801,7 +3811,7 @@ static int do_check(struct bpf_verifier_env *env) | ||
434 | */ | ||
435 | err = check_mem_access(env, insn_idx, insn->src_reg, insn->off, | ||
436 | BPF_SIZE(insn->code), BPF_READ, | ||
437 | - insn->dst_reg); | ||
438 | + insn->dst_reg, false); | ||
439 | if (err) | ||
440 | return err; | ||
441 | |||
442 | @@ -3853,7 +3863,7 @@ static int do_check(struct bpf_verifier_env *env) | ||
443 | /* check that memory (dst_reg + off) is writeable */ | ||
444 | err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, | ||
445 | BPF_SIZE(insn->code), BPF_WRITE, | ||
446 | - insn->src_reg); | ||
447 | + insn->src_reg, false); | ||
448 | if (err) | ||
449 | return err; | ||
450 | |||
451 | @@ -3888,7 +3898,7 @@ static int do_check(struct bpf_verifier_env *env) | ||
452 | /* check that memory (dst_reg + off) is writeable */ | ||
453 | err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, | ||
454 | BPF_SIZE(insn->code), BPF_WRITE, | ||
455 | - -1); | ||
456 | + -1, false); | ||
457 | if (err) | ||
458 | return err; | ||
459 | |||
460 | diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c | ||
461 | index c55d265489ca..9167ee976314 100644 | ||
462 | --- a/tools/testing/selftests/bpf/test_verifier.c | ||
463 | +++ b/tools/testing/selftests/bpf/test_verifier.c | ||
464 | @@ -2257,6 +2257,32 @@ static struct bpf_test tests[] = { | ||
465 | .result_unpriv = REJECT, | ||
466 | .result = ACCEPT, | ||
467 | }, | ||
468 | + { | ||
469 | + "runtime/jit: pass negative index to tail_call", | ||
470 | + .insns = { | ||
471 | + BPF_MOV64_IMM(BPF_REG_3, -1), | ||
472 | + BPF_LD_MAP_FD(BPF_REG_2, 0), | ||
473 | + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
474 | + BPF_FUNC_tail_call), | ||
475 | + BPF_MOV64_IMM(BPF_REG_0, 0), | ||
476 | + BPF_EXIT_INSN(), | ||
477 | + }, | ||
478 | + .fixup_prog = { 1 }, | ||
479 | + .result = ACCEPT, | ||
480 | + }, | ||
481 | + { | ||
482 | + "runtime/jit: pass > 32bit index to tail_call", | ||
483 | + .insns = { | ||
484 | + BPF_LD_IMM64(BPF_REG_3, 0x100000000ULL), | ||
485 | + BPF_LD_MAP_FD(BPF_REG_2, 0), | ||
486 | + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
487 | + BPF_FUNC_tail_call), | ||
488 | + BPF_MOV64_IMM(BPF_REG_0, 0), | ||
489 | + BPF_EXIT_INSN(), | ||
490 | + }, | ||
491 | + .fixup_prog = { 2 }, | ||
492 | + .result = ACCEPT, | ||
493 | + }, | ||
494 | { | ||
495 | "stack pointer arithmetic", | ||
496 | .insns = { | ||
497 | @@ -7854,6 +7880,64 @@ static struct bpf_test tests[] = { | ||
498 | .prog_type = BPF_PROG_TYPE_XDP, | ||
499 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
500 | }, | ||
501 | + { | ||
502 | + "xadd/w check unaligned stack", | ||
503 | + .insns = { | ||
504 | + BPF_MOV64_IMM(BPF_REG_0, 1), | ||
505 | + BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), | ||
506 | + BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -7), | ||
507 | + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), | ||
508 | + BPF_EXIT_INSN(), | ||
509 | + }, | ||
510 | + .result = REJECT, | ||
511 | + .errstr = "misaligned stack access off", | ||
512 | + .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
513 | + }, | ||
514 | + { | ||
515 | + "xadd/w check unaligned map", | ||
516 | + .insns = { | ||
517 | + BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
518 | + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
519 | + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
520 | + BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
521 | + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
522 | + BPF_FUNC_map_lookup_elem), | ||
523 | + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
524 | + BPF_EXIT_INSN(), | ||
525 | + BPF_MOV64_IMM(BPF_REG_1, 1), | ||
526 | + BPF_STX_XADD(BPF_W, BPF_REG_0, BPF_REG_1, 3), | ||
527 | + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 3), | ||
528 | + BPF_EXIT_INSN(), | ||
529 | + }, | ||
530 | + .fixup_map1 = { 3 }, | ||
531 | + .result = REJECT, | ||
532 | + .errstr = "misaligned value access off", | ||
533 | + .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
534 | + }, | ||
535 | + { | ||
536 | + "xadd/w check unaligned pkt", | ||
537 | + .insns = { | ||
538 | + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
539 | + offsetof(struct xdp_md, data)), | ||
540 | + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
541 | + offsetof(struct xdp_md, data_end)), | ||
542 | + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
543 | + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
544 | + BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 2), | ||
545 | + BPF_MOV64_IMM(BPF_REG_0, 99), | ||
546 | + BPF_JMP_IMM(BPF_JA, 0, 0, 6), | ||
547 | + BPF_MOV64_IMM(BPF_REG_0, 1), | ||
548 | + BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), | ||
549 | + BPF_ST_MEM(BPF_W, BPF_REG_2, 3, 0), | ||
550 | + BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 1), | ||
551 | + BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 2), | ||
552 | + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 1), | ||
553 | + BPF_EXIT_INSN(), | ||
554 | + }, | ||
555 | + .result = REJECT, | ||
556 | + .errstr = "BPF_XADD stores into R2 packet", | ||
557 | + .prog_type = BPF_PROG_TYPE_XDP, | ||
558 | + }, | ||
559 | }; | ||
560 | |||
561 | static int probe_filter_length(const struct bpf_insn *fp) |