lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sat, 4 Jun 2022 00:18:08 -0700
From:   Martin KaFai Lau <kafai@...com>
To:     Stanislav Fomichev <sdf@...gle.com>
Cc:     netdev@...r.kernel.org, bpf@...r.kernel.org, ast@...nel.org,
        daniel@...earbox.net, andrii@...nel.org
Subject: Re: [PATCH bpf-next v8 06/11] bpf: allow writing to a subset of sock
 fields from lsm progtype

On Wed, Jun 01, 2022 at 12:02:13PM -0700, Stanislav Fomichev wrote:
> For now, allow only the obvious ones, like sk_priority and sk_mark.
> 
> Signed-off-by: Stanislav Fomichev <sdf@...gle.com>
> ---
>  kernel/bpf/bpf_lsm.c  | 58 +++++++++++++++++++++++++++++++++++++++++++
>  kernel/bpf/verifier.c |  3 ++-
>  2 files changed, 60 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c
> index 83aa431dd52e..feba8e96f58d 100644
> --- a/kernel/bpf/bpf_lsm.c
> +++ b/kernel/bpf/bpf_lsm.c
> @@ -303,7 +303,65 @@ bool bpf_lsm_is_sleepable_hook(u32 btf_id)
>  const struct bpf_prog_ops lsm_prog_ops = {
>  };
>  
> +static int lsm_btf_struct_access(struct bpf_verifier_log *log,
> +					const struct btf *btf,
> +					const struct btf_type *t, int off,
> +					int size, enum bpf_access_type atype,
> +					u32 *next_btf_id,
> +					enum bpf_type_flag *flag)
> +{
> +	const struct btf_type *sock_type;
> +	struct btf *btf_vmlinux;
> +	s32 type_id;
> +	size_t end;
> +
> +	if (atype == BPF_READ)
> +		return btf_struct_access(log, btf, t, off, size, atype, next_btf_id,
> +					 flag);
> +
> +	btf_vmlinux = bpf_get_btf_vmlinux();
> +	if (!btf_vmlinux) {
> +		bpf_log(log, "no vmlinux btf\n");
> +		return -EOPNOTSUPP;
> +	}
> +
> +	type_id = btf_find_by_name_kind(btf_vmlinux, "sock", BTF_KIND_STRUCT);
> +	if (type_id < 0) {
> +		bpf_log(log, "'struct sock' not found in vmlinux btf\n");
> +		return -EINVAL;
> +	}
> +
> +	sock_type = btf_type_by_id(btf_vmlinux, type_id);
> +
> +	if (t != sock_type) {
> +		bpf_log(log, "only 'struct sock' writes are supported\n");
> +		return -EACCES;
> +	}
> +
> +	switch (off) {
> +	case bpf_ctx_range(struct sock, sk_priority):
This looks wrong.  It should not allow to write at
any bytes of the '__u32 sk_priority'.

> +		end = offsetofend(struct sock, sk_priority);
> +		break;
> +	case bpf_ctx_range(struct sock, sk_mark):
Same here.

Just came to my mind,
if the current need is only sk_priority and sk_mark,
do you think allowing bpf_setsockopt will be more useful instead ?
It currently has SO_MARK, SO_PRIORITY, and other options.
Also, changing SO_MARK requires to clear the sk->sk_dst_cache.
In general, is it safe to do bpf_setsockopt in all bpf_lsm hooks ?

> +		end = offsetofend(struct sock, sk_mark);
> +		break;
> +	default:
> +		bpf_log(log, "no write support to 'struct sock' at off %d\n", off);
> +		return -EACCES;
> +	}
> +
> +	if (off + size > end) {
> +		bpf_log(log,
> +			"write access at off %d with size %d beyond the member of 'struct sock' ended at %zu\n",
> +			off, size, end);
> +		return -EACCES;
> +	}
> +
> +	return NOT_INIT;
> +}
> +
>  const struct bpf_verifier_ops lsm_verifier_ops = {
>  	.get_func_proto = bpf_lsm_func_proto,
>  	.is_valid_access = btf_ctx_access,
> +	.btf_struct_access = lsm_btf_struct_access,
>  };
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index caa5740b39b3..c54e171d9c23 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -13413,7 +13413,8 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
>  				insn->code = BPF_LDX | BPF_PROBE_MEM |
>  					BPF_SIZE((insn)->code);
>  				env->prog->aux->num_exentries++;
> -			} else if (resolve_prog_type(env->prog) != BPF_PROG_TYPE_STRUCT_OPS) {
> +			} else if (resolve_prog_type(env->prog) != BPF_PROG_TYPE_STRUCT_OPS &&
> +				   resolve_prog_type(env->prog) != BPF_PROG_TYPE_LSM) {
>  				verbose(env, "Writes through BTF pointers are not allowed\n");
>  				return -EINVAL;
>  			}
> -- 
> 2.36.1.255.ge46751e96f-goog
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ