mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	bpf: bpf_prog_array_copy() should return -ENOENT if exclude_prog not found
This makes is it possible for bpf prog detach to return -ENOENT. Acked-by: Yonghong Song <yhs@fb.com> Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
		
							parent
							
								
									9ce64f192d
								
							
						
					
					
						commit
						170a7e3ea0
					
				
					 2 changed files with 11 additions and 2 deletions
				
			
		| 
						 | 
					@ -1616,6 +1616,7 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
 | 
				
			||||||
	int new_prog_cnt, carry_prog_cnt = 0;
 | 
						int new_prog_cnt, carry_prog_cnt = 0;
 | 
				
			||||||
	struct bpf_prog **existing_prog;
 | 
						struct bpf_prog **existing_prog;
 | 
				
			||||||
	struct bpf_prog_array *array;
 | 
						struct bpf_prog_array *array;
 | 
				
			||||||
 | 
						bool found_exclude = false;
 | 
				
			||||||
	int new_prog_idx = 0;
 | 
						int new_prog_idx = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Figure out how many existing progs we need to carry over to
 | 
						/* Figure out how many existing progs we need to carry over to
 | 
				
			||||||
| 
						 | 
					@ -1624,14 +1625,20 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
 | 
				
			||||||
	if (old_array) {
 | 
						if (old_array) {
 | 
				
			||||||
		existing_prog = old_array->progs;
 | 
							existing_prog = old_array->progs;
 | 
				
			||||||
		for (; *existing_prog; existing_prog++) {
 | 
							for (; *existing_prog; existing_prog++) {
 | 
				
			||||||
			if (*existing_prog != exclude_prog &&
 | 
								if (*existing_prog == exclude_prog) {
 | 
				
			||||||
			    *existing_prog != &dummy_bpf_prog.prog)
 | 
									found_exclude = true;
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (*existing_prog != &dummy_bpf_prog.prog)
 | 
				
			||||||
				carry_prog_cnt++;
 | 
									carry_prog_cnt++;
 | 
				
			||||||
			if (*existing_prog == include_prog)
 | 
								if (*existing_prog == include_prog)
 | 
				
			||||||
				return -EEXIST;
 | 
									return -EEXIST;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (exclude_prog && !found_exclude)
 | 
				
			||||||
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* How many progs (not NULL) will be in the new array? */
 | 
						/* How many progs (not NULL) will be in the new array? */
 | 
				
			||||||
	new_prog_cnt = carry_prog_cnt;
 | 
						new_prog_cnt = carry_prog_cnt;
 | 
				
			||||||
	if (include_prog)
 | 
						if (include_prog)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1006,6 +1006,8 @@ void perf_event_detach_bpf_prog(struct perf_event *event)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	old_array = event->tp_event->prog_array;
 | 
						old_array = event->tp_event->prog_array;
 | 
				
			||||||
	ret = bpf_prog_array_copy(old_array, event->prog, NULL, &new_array);
 | 
						ret = bpf_prog_array_copy(old_array, event->prog, NULL, &new_array);
 | 
				
			||||||
 | 
						if (ret == -ENOENT)
 | 
				
			||||||
 | 
							goto unlock;
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		bpf_prog_array_delete_safe(old_array, event->prog);
 | 
							bpf_prog_array_delete_safe(old_array, event->prog);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue