diff options
Diffstat (limited to 'kernel/bpf/core.c')
| -rw-r--r-- | kernel/bpf/core.c | 31 | 
1 files changed, 22 insertions, 9 deletions
| diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index ed0b3578867c..9268d77898b7 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -25,7 +25,7 @@  #include <linux/moduleloader.h>  #include <linux/bpf.h>  #include <linux/btf.h> -#include <linux/frame.h> +#include <linux/objtool.h>  #include <linux/rbtree_latch.h>  #include <linux/kallsyms.h>  #include <linux/rcupdate.h> @@ -98,6 +98,8 @@ struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flag  	fp->jit_requested = ebpf_jit_enabled();  	INIT_LIST_HEAD_RCU(&fp->aux->ksym.lnode); +	mutex_init(&fp->aux->used_maps_mutex); +	mutex_init(&fp->aux->dst_mutex);  	return fp;  } @@ -253,6 +255,8 @@ struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size,  void __bpf_prog_free(struct bpf_prog *fp)  {  	if (fp->aux) { +		mutex_destroy(&fp->aux->used_maps_mutex); +		mutex_destroy(&fp->aux->dst_mutex);  		free_percpu(fp->aux->stats);  		kfree(fp->aux->poke_tab);  		kfree(fp->aux); @@ -773,7 +777,8 @@ int bpf_jit_add_poke_descriptor(struct bpf_prog *prog,  	if (size > poke_tab_max)  		return -ENOSPC; -	if (poke->ip || poke->ip_stable || poke->adj_off) +	if (poke->tailcall_target || poke->tailcall_target_stable || +	    poke->tailcall_bypass || poke->adj_off || poke->bypass_addr)  		return -EINVAL;  	switch (poke->reason) { @@ -1747,8 +1752,9 @@ bool bpf_prog_array_compatible(struct bpf_array *array,  static int bpf_check_tail_call(const struct bpf_prog *fp)  {  	struct bpf_prog_aux *aux = fp->aux; -	int i; +	int i, ret = 0; +	mutex_lock(&aux->used_maps_mutex);  	for (i = 0; i < aux->used_map_cnt; i++) {  		struct bpf_map *map = aux->used_maps[i];  		struct bpf_array *array; @@ -1757,11 +1763,15 @@ static int bpf_check_tail_call(const struct bpf_prog *fp)  			continue;  		array = container_of(map, struct bpf_array, map); -		if (!bpf_prog_array_compatible(array, fp)) -			return -EINVAL; +		if (!bpf_prog_array_compatible(array, fp)) { +			ret = -EINVAL; +			goto out; +		}  	} -	return 0; +out: +	mutex_unlock(&aux->used_maps_mutex); +	return ret;  }  static void bpf_prog_select_func(struct bpf_prog *fp) @@ -2130,7 +2140,8 @@ static void bpf_prog_free_deferred(struct work_struct *work)  	if (aux->prog->has_callchain_buf)  		put_callchain_buffers();  #endif -	bpf_trampoline_put(aux->trampoline); +	if (aux->dst_trampoline) +		bpf_trampoline_put(aux->dst_trampoline);  	for (i = 0; i < aux->func_cnt; i++)  		bpf_jit_free(aux->func[i]);  	if (aux->func_cnt) { @@ -2146,8 +2157,8 @@ void bpf_prog_free(struct bpf_prog *fp)  {  	struct bpf_prog_aux *aux = fp->aux; -	if (aux->linked_prog) -		bpf_prog_put(aux->linked_prog); +	if (aux->dst_prog) +		bpf_prog_put(aux->dst_prog);  	INIT_WORK(&aux->work, bpf_prog_free_deferred);  	schedule_work(&aux->work);  } @@ -2208,6 +2219,8 @@ const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;  const struct bpf_func_proto bpf_get_current_ancestor_cgroup_id_proto __weak;  const struct bpf_func_proto bpf_get_local_storage_proto __weak;  const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto __weak; +const struct bpf_func_proto bpf_snprintf_btf_proto __weak; +const struct bpf_func_proto bpf_seq_printf_btf_proto __weak;  const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)  { | 
