diff options
Diffstat (limited to 'kernel/trace/bpf_trace.c')
| -rw-r--r-- | kernel/trace/bpf_trace.c | 81 | 
1 files changed, 67 insertions, 14 deletions
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 623dd0684429..21aa30644219 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -345,7 +345,7 @@ static const struct bpf_func_proto bpf_probe_write_user_proto = {  	.gpl_only	= true,  	.ret_type	= RET_INTEGER,  	.arg1_type	= ARG_ANYTHING, -	.arg2_type	= ARG_PTR_TO_MEM, +	.arg2_type	= ARG_PTR_TO_MEM | MEM_RDONLY,  	.arg3_type	= ARG_CONST_SIZE,  }; @@ -394,7 +394,7 @@ static const struct bpf_func_proto bpf_trace_printk_proto = {  	.func		= bpf_trace_printk,  	.gpl_only	= true,  	.ret_type	= RET_INTEGER, -	.arg1_type	= ARG_PTR_TO_MEM, +	.arg1_type	= ARG_PTR_TO_MEM | MEM_RDONLY,  	.arg2_type	= ARG_CONST_SIZE,  }; @@ -450,9 +450,9 @@ static const struct bpf_func_proto bpf_trace_vprintk_proto = {  	.func		= bpf_trace_vprintk,  	.gpl_only	= true,  	.ret_type	= RET_INTEGER, -	.arg1_type	= ARG_PTR_TO_MEM, +	.arg1_type	= ARG_PTR_TO_MEM | MEM_RDONLY,  	.arg2_type	= ARG_CONST_SIZE, -	.arg3_type	= ARG_PTR_TO_MEM_OR_NULL, +	.arg3_type	= ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY,  	.arg4_type	= ARG_CONST_SIZE_OR_ZERO,  }; @@ -492,9 +492,9 @@ static const struct bpf_func_proto bpf_seq_printf_proto = {  	.ret_type	= RET_INTEGER,  	.arg1_type	= ARG_PTR_TO_BTF_ID,  	.arg1_btf_id	= &btf_seq_file_ids[0], -	.arg2_type	= ARG_PTR_TO_MEM, +	.arg2_type	= ARG_PTR_TO_MEM | MEM_RDONLY,  	.arg3_type	= ARG_CONST_SIZE, -	.arg4_type      = ARG_PTR_TO_MEM_OR_NULL, +	.arg4_type      = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY,  	.arg5_type      = ARG_CONST_SIZE_OR_ZERO,  }; @@ -509,7 +509,7 @@ static const struct bpf_func_proto bpf_seq_write_proto = {  	.ret_type	= RET_INTEGER,  	.arg1_type	= ARG_PTR_TO_BTF_ID,  	.arg1_btf_id	= &btf_seq_file_ids[0], -	.arg2_type	= ARG_PTR_TO_MEM, +	.arg2_type	= ARG_PTR_TO_MEM | MEM_RDONLY,  	.arg3_type	= ARG_CONST_SIZE_OR_ZERO,  }; @@ -533,7 +533,7 @@ static const struct bpf_func_proto bpf_seq_printf_btf_proto = {  	.ret_type	= RET_INTEGER,  	.arg1_type	= ARG_PTR_TO_BTF_ID,  	.arg1_btf_id	= &btf_seq_file_ids[0], -	.arg2_type	= ARG_PTR_TO_MEM, +	.arg2_type	= ARG_PTR_TO_MEM | MEM_RDONLY,  	.arg3_type	= ARG_CONST_SIZE_OR_ZERO,  	.arg4_type	= ARG_ANYTHING,  }; @@ -694,7 +694,7 @@ static const struct bpf_func_proto bpf_perf_event_output_proto = {  	.arg1_type	= ARG_PTR_TO_CTX,  	.arg2_type	= ARG_CONST_MAP_PTR,  	.arg3_type	= ARG_ANYTHING, -	.arg4_type	= ARG_PTR_TO_MEM, +	.arg4_type	= ARG_PTR_TO_MEM | MEM_RDONLY,  	.arg5_type	= ARG_CONST_SIZE_OR_ZERO,  }; @@ -1004,7 +1004,7 @@ const struct bpf_func_proto bpf_snprintf_btf_proto = {  	.ret_type	= RET_INTEGER,  	.arg1_type	= ARG_PTR_TO_MEM,  	.arg2_type	= ARG_CONST_SIZE, -	.arg3_type	= ARG_PTR_TO_MEM, +	.arg3_type	= ARG_PTR_TO_MEM | MEM_RDONLY,  	.arg4_type	= ARG_CONST_SIZE,  	.arg5_type	= ARG_ANYTHING,  }; @@ -1012,7 +1012,7 @@ const struct bpf_func_proto bpf_snprintf_btf_proto = {  BPF_CALL_1(bpf_get_func_ip_tracing, void *, ctx)  {  	/* This helper call is inlined by verifier. */ -	return ((u64 *)ctx)[-1]; +	return ((u64 *)ctx)[-2];  }  static const struct bpf_func_proto bpf_get_func_ip_proto_tracing = { @@ -1091,6 +1091,53 @@ static const struct bpf_func_proto bpf_get_branch_snapshot_proto = {  	.arg2_type	= ARG_CONST_SIZE_OR_ZERO,  }; +BPF_CALL_3(get_func_arg, void *, ctx, u32, n, u64 *, value) +{ +	/* This helper call is inlined by verifier. */ +	u64 nr_args = ((u64 *)ctx)[-1]; + +	if ((u64) n >= nr_args) +		return -EINVAL; +	*value = ((u64 *)ctx)[n]; +	return 0; +} + +static const struct bpf_func_proto bpf_get_func_arg_proto = { +	.func		= get_func_arg, +	.ret_type	= RET_INTEGER, +	.arg1_type	= ARG_PTR_TO_CTX, +	.arg2_type	= ARG_ANYTHING, +	.arg3_type	= ARG_PTR_TO_LONG, +}; + +BPF_CALL_2(get_func_ret, void *, ctx, u64 *, value) +{ +	/* This helper call is inlined by verifier. */ +	u64 nr_args = ((u64 *)ctx)[-1]; + +	*value = ((u64 *)ctx)[nr_args]; +	return 0; +} + +static const struct bpf_func_proto bpf_get_func_ret_proto = { +	.func		= get_func_ret, +	.ret_type	= RET_INTEGER, +	.arg1_type	= ARG_PTR_TO_CTX, +	.arg2_type	= ARG_PTR_TO_LONG, +}; + +BPF_CALL_1(get_func_arg_cnt, void *, ctx) +{ +	/* This helper call is inlined by verifier. */ +	return ((u64 *)ctx)[-1]; +} + +static const struct bpf_func_proto bpf_get_func_arg_cnt_proto = { +	.func		= get_func_arg_cnt, +	.ret_type	= RET_INTEGER, +	.arg1_type	= ARG_PTR_TO_CTX, +}; +  static const struct bpf_func_proto *  bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)  { @@ -1287,7 +1334,7 @@ static const struct bpf_func_proto bpf_perf_event_output_proto_tp = {  	.arg1_type	= ARG_PTR_TO_CTX,  	.arg2_type	= ARG_CONST_MAP_PTR,  	.arg3_type	= ARG_ANYTHING, -	.arg4_type	= ARG_PTR_TO_MEM, +	.arg4_type	= ARG_PTR_TO_MEM | MEM_RDONLY,  	.arg5_type	= ARG_CONST_SIZE_OR_ZERO,  }; @@ -1509,7 +1556,7 @@ static const struct bpf_func_proto bpf_perf_event_output_proto_raw_tp = {  	.arg1_type	= ARG_PTR_TO_CTX,  	.arg2_type	= ARG_CONST_MAP_PTR,  	.arg3_type	= ARG_ANYTHING, -	.arg4_type	= ARG_PTR_TO_MEM, +	.arg4_type	= ARG_PTR_TO_MEM | MEM_RDONLY,  	.arg5_type	= ARG_CONST_SIZE_OR_ZERO,  }; @@ -1563,7 +1610,7 @@ static const struct bpf_func_proto bpf_get_stack_proto_raw_tp = {  	.gpl_only	= true,  	.ret_type	= RET_INTEGER,  	.arg1_type	= ARG_PTR_TO_CTX, -	.arg2_type	= ARG_PTR_TO_MEM, +	.arg2_type	= ARG_PTR_TO_MEM | MEM_RDONLY,  	.arg3_type	= ARG_CONST_SIZE_OR_ZERO,  	.arg4_type	= ARG_ANYTHING,  }; @@ -1629,6 +1676,12 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)  		       NULL;  	case BPF_FUNC_d_path:  		return &bpf_d_path_proto; +	case BPF_FUNC_get_func_arg: +		return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_proto : NULL; +	case BPF_FUNC_get_func_ret: +		return bpf_prog_has_trampoline(prog) ? &bpf_get_func_ret_proto : NULL; +	case BPF_FUNC_get_func_arg_cnt: +		return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL;  	default:  		fn = raw_tp_prog_func_proto(func_id, prog);  		if (!fn && prog->expected_attach_type == BPF_TRACE_ITER)  | 
