forked from mirrors/linux
		
	selftests/bpf: Add test for prealloc_lru_pop bug
Add a regression test to check against invalid check_and_init_map_value call inside prealloc_lru_pop. The kptr should not be reset to NULL once we set it after deleting the map element. Hence, we trigger a program that updates the element causing its reuse, and checks whether the unref kptr is reset or not. If it is, prealloc_lru_pop does an incorrect check_and_init_map_value call and the test fails. Acked-by: Yonghong Song <yhs@fb.com> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20220809213033.24147-4-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
		
							parent
							
								
									275c30bcee
								
							
						
					
					
						commit
						de7b992710
					
				
					 2 changed files with 70 additions and 0 deletions
				
			
		
							
								
								
									
										21
									
								
								tools/testing/selftests/bpf/prog_tests/lru_bug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								tools/testing/selftests/bpf/prog_tests/lru_bug.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0
 | ||||||
|  | #include <test_progs.h> | ||||||
|  | 
 | ||||||
|  | #include "lru_bug.skel.h" | ||||||
|  | 
 | ||||||
|  | void test_lru_bug(void) | ||||||
|  | { | ||||||
|  | 	struct lru_bug *skel; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	skel = lru_bug__open_and_load(); | ||||||
|  | 	if (!ASSERT_OK_PTR(skel, "lru_bug__open_and_load")) | ||||||
|  | 		return; | ||||||
|  | 	ret = lru_bug__attach(skel); | ||||||
|  | 	if (!ASSERT_OK(ret, "lru_bug__attach")) | ||||||
|  | 		goto end; | ||||||
|  | 	usleep(1); | ||||||
|  | 	ASSERT_OK(skel->data->result, "prealloc_lru_pop doesn't call check_and_init_map_value"); | ||||||
|  | end: | ||||||
|  | 	lru_bug__destroy(skel); | ||||||
|  | } | ||||||
							
								
								
									
										49
									
								
								tools/testing/selftests/bpf/progs/lru_bug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								tools/testing/selftests/bpf/progs/lru_bug.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0
 | ||||||
|  | #include <vmlinux.h> | ||||||
|  | #include <bpf/bpf_tracing.h> | ||||||
|  | #include <bpf/bpf_helpers.h> | ||||||
|  | 
 | ||||||
|  | struct map_value { | ||||||
|  | 	struct task_struct __kptr *ptr; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct { | ||||||
|  | 	__uint(type, BPF_MAP_TYPE_LRU_HASH); | ||||||
|  | 	__uint(max_entries, 1); | ||||||
|  | 	__type(key, int); | ||||||
|  | 	__type(value, struct map_value); | ||||||
|  | } lru_map SEC(".maps"); | ||||||
|  | 
 | ||||||
|  | int pid = 0; | ||||||
|  | int result = 1; | ||||||
|  | 
 | ||||||
|  | SEC("fentry/bpf_ktime_get_ns") | ||||||
|  | int printk(void *ctx) | ||||||
|  | { | ||||||
|  | 	struct map_value v = {}; | ||||||
|  | 
 | ||||||
|  | 	if (pid == bpf_get_current_task_btf()->pid) | ||||||
|  | 		bpf_map_update_elem(&lru_map, &(int){0}, &v, 0); | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SEC("fentry/do_nanosleep") | ||||||
|  | int nanosleep(void *ctx) | ||||||
|  | { | ||||||
|  | 	struct map_value val = {}, *v; | ||||||
|  | 	struct task_struct *current; | ||||||
|  | 
 | ||||||
|  | 	bpf_map_update_elem(&lru_map, &(int){0}, &val, 0); | ||||||
|  | 	v = bpf_map_lookup_elem(&lru_map, &(int){0}); | ||||||
|  | 	if (!v) | ||||||
|  | 		return 0; | ||||||
|  | 	bpf_map_delete_elem(&lru_map, &(int){0}); | ||||||
|  | 	current = bpf_get_current_task_btf(); | ||||||
|  | 	v->ptr = current; | ||||||
|  | 	pid = current->pid; | ||||||
|  | 	bpf_ktime_get_ns(); | ||||||
|  | 	result = !v->ptr; | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char _license[] SEC("license") = "GPL"; | ||||||
		Loading…
	
		Reference in a new issue
	
	 Kumar Kartikeya Dwivedi
						Kumar Kartikeya Dwivedi