@@ -1837,6 +1837,19 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
18371837 }
18381838}
18391839
1840+ static bool arg_type_is_mem_ptr (enum bpf_arg_type type )
1841+ {
1842+ return type == ARG_PTR_TO_MEM ||
1843+ type == ARG_PTR_TO_MEM_OR_NULL ||
1844+ type == ARG_PTR_TO_UNINIT_MEM ;
1845+ }
1846+
1847+ static bool arg_type_is_mem_size (enum bpf_arg_type type )
1848+ {
1849+ return type == ARG_CONST_SIZE ||
1850+ type == ARG_CONST_SIZE_OR_ZERO ;
1851+ }
1852+
18401853static int check_func_arg (struct bpf_verifier_env * env , u32 regno ,
18411854 enum bpf_arg_type arg_type ,
18421855 struct bpf_call_arg_meta * meta )
@@ -1886,9 +1899,7 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
18861899 expected_type = PTR_TO_CTX ;
18871900 if (type != expected_type )
18881901 goto err_type ;
1889- } else if (arg_type == ARG_PTR_TO_MEM ||
1890- arg_type == ARG_PTR_TO_MEM_OR_NULL ||
1891- arg_type == ARG_PTR_TO_UNINIT_MEM ) {
1902+ } else if (arg_type_is_mem_ptr (arg_type )) {
18921903 expected_type = PTR_TO_STACK ;
18931904 /* One exception here. In case function allows for NULL to be
18941905 * passed in as argument, it's a SCALAR_VALUE type. Final test
@@ -1949,25 +1960,12 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
19491960 err = check_stack_boundary (env , regno ,
19501961 meta -> map_ptr -> value_size ,
19511962 false, NULL );
1952- } else if (arg_type == ARG_CONST_SIZE ||
1953- arg_type == ARG_CONST_SIZE_OR_ZERO ) {
1963+ } else if (arg_type_is_mem_size (arg_type )) {
19541964 bool zero_size_allowed = (arg_type == ARG_CONST_SIZE_OR_ZERO );
19551965
1956- /* bpf_xxx(..., buf, len) call will access 'len' bytes
1957- * from stack pointer 'buf'. Check it
1958- * note: regno == len, regno - 1 == buf
1959- */
1960- if (regno == 0 ) {
1961- /* kernel subsystem misconfigured verifier */
1962- verbose (env ,
1963- "ARG_CONST_SIZE cannot be first argument\n" );
1964- return - EACCES ;
1965- }
1966-
19671966 /* The register is SCALAR_VALUE; the access check
19681967 * happens using its boundaries.
19691968 */
1970-
19711969 if (!tnum_is_const (reg -> var_off ))
19721970 /* For unprivileged variable accesses, disable raw
19731971 * mode so that the program is required to
@@ -2111,7 +2109,7 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
21112109 return - EINVAL ;
21122110}
21132111
2114- static int check_raw_mode (const struct bpf_func_proto * fn )
2112+ static bool check_raw_mode_ok (const struct bpf_func_proto * fn )
21152113{
21162114 int count = 0 ;
21172115
@@ -2126,7 +2124,44 @@ static int check_raw_mode(const struct bpf_func_proto *fn)
21262124 if (fn -> arg5_type == ARG_PTR_TO_UNINIT_MEM )
21272125 count ++ ;
21282126
2129- return count > 1 ? - EINVAL : 0 ;
2127+ /* We only support one arg being in raw mode at the moment,
2128+ * which is sufficient for the helper functions we have
2129+ * right now.
2130+ */
2131+ return count <= 1 ;
2132+ }
2133+
2134+ static bool check_args_pair_invalid (enum bpf_arg_type arg_curr ,
2135+ enum bpf_arg_type arg_next )
2136+ {
2137+ return (arg_type_is_mem_ptr (arg_curr ) &&
2138+ !arg_type_is_mem_size (arg_next )) ||
2139+ (!arg_type_is_mem_ptr (arg_curr ) &&
2140+ arg_type_is_mem_size (arg_next ));
2141+ }
2142+
2143+ static bool check_arg_pair_ok (const struct bpf_func_proto * fn )
2144+ {
2145+ /* bpf_xxx(..., buf, len) call will access 'len'
2146+ * bytes from memory 'buf'. Both arg types need
2147+ * to be paired, so make sure there's no buggy
2148+ * helper function specification.
2149+ */
2150+ if (arg_type_is_mem_size (fn -> arg1_type ) ||
2151+ arg_type_is_mem_ptr (fn -> arg5_type ) ||
2152+ check_args_pair_invalid (fn -> arg1_type , fn -> arg2_type ) ||
2153+ check_args_pair_invalid (fn -> arg2_type , fn -> arg3_type ) ||
2154+ check_args_pair_invalid (fn -> arg3_type , fn -> arg4_type ) ||
2155+ check_args_pair_invalid (fn -> arg4_type , fn -> arg5_type ))
2156+ return false;
2157+
2158+ return true;
2159+ }
2160+
2161+ static int check_func_proto (const struct bpf_func_proto * fn )
2162+ {
2163+ return check_raw_mode_ok (fn ) &&
2164+ check_arg_pair_ok (fn ) ? 0 : - EINVAL ;
21302165}
21312166
21322167/* Packet data might have moved, any old PTR_TO_PACKET[_META,_END]
@@ -2282,7 +2317,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
22822317
22832318 if (env -> ops -> get_func_proto )
22842319 fn = env -> ops -> get_func_proto (func_id );
2285-
22862320 if (!fn ) {
22872321 verbose (env , "unknown func %s#%d\n" , func_id_name (func_id ),
22882322 func_id );
@@ -2306,10 +2340,7 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
23062340 memset (& meta , 0 , sizeof (meta ));
23072341 meta .pkt_access = fn -> pkt_access ;
23082342
2309- /* We only support one arg being in raw mode at the moment, which
2310- * is sufficient for the helper functions we have right now.
2311- */
2312- err = check_raw_mode (fn );
2343+ err = check_func_proto (fn );
23132344 if (err ) {
23142345 verbose (env , "kernel subsystem misconfigured func %s#%d\n" ,
23152346 func_id_name (func_id ), func_id );
0 commit comments