diff options
Diffstat (limited to 'kernel/bpf/btf.c')
| -rw-r--r-- | kernel/bpf/btf.c | 25 | 
1 files changed, 13 insertions, 12 deletions
| diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 817204d53372..249657c466dd 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -29,6 +29,7 @@  #include <net/netfilter/nf_bpf_link.h>  #include <net/sock.h> +#include <net/xdp.h>  #include "../tools/lib/bpf/relo_core.h"  /* BTF (BPF Type Format) is the meta data format which describes @@ -6133,8 +6134,9 @@ static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,  	const char *tname, *mname, *tag_value;  	u32 vlen, elem_id, mid; -	*flag = 0;  again: +	if (btf_type_is_modifier(t)) +		t = btf_type_skip_modifiers(btf, t->type, NULL);  	tname = __btf_name_by_offset(btf, t->name_off);  	if (!btf_type_is_struct(t)) {  		bpf_log(log, "Type '%s' is not a struct\n", tname); @@ -6142,6 +6144,14 @@ again:  	}  	vlen = btf_type_vlen(t); +	if (BTF_INFO_KIND(t->info) == BTF_KIND_UNION && vlen != 1 && !(*flag & PTR_UNTRUSTED)) +		/* +		 * walking unions yields untrusted pointers +		 * with exception of __bpf_md_ptr and other +		 * unions with a single member +		 */ +		*flag |= PTR_UNTRUSTED; +  	if (off + size > t->size) {  		/* If the last element is a variable size array, we may  		 * need to relax the rule. @@ -6302,15 +6312,6 @@ error:  		 * of this field or inside of this struct  		 */  		if (btf_type_is_struct(mtype)) { -			if (BTF_INFO_KIND(mtype->info) == BTF_KIND_UNION && -			    btf_type_vlen(mtype) != 1) -				/* -				 * walking unions yields untrusted pointers -				 * with exception of __bpf_md_ptr and other -				 * unions with a single member -				 */ -				*flag |= PTR_UNTRUSTED; -  			/* our field must be inside that union or struct */  			t = mtype; @@ -6368,7 +6369,7 @@ error:  		 * that also allows using an array of int as a scratch  		 * space. e.g. skb->cb[].  		 */ -		if (off + size > mtrue_end) { +		if (off + size > mtrue_end && !(*flag & PTR_UNTRUSTED)) {  			bpf_log(log,  				"access beyond the end of member %s (mend:%u) in struct %s with off %u size %u\n",  				mname, mtrue_end, tname, off, size); @@ -6476,7 +6477,7 @@ bool btf_struct_ids_match(struct bpf_verifier_log *log,  			  bool strict)  {  	const struct btf_type *type; -	enum bpf_type_flag flag; +	enum bpf_type_flag flag = 0;  	int err;  	/* Are we already done? */ | 
