[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190508160859.4380-1-krzesimir@kinvolk.io>
Date: Wed, 8 May 2019 18:08:58 +0200
From: Krzesimir Nowak <krzesimir@...volk.io>
To: bpf@...r.kernel.org
Cc: Krzesimir Nowak <krzesimir@...volk.io>,
Alban Crequy <alban@...volk.io>,
Iago López Galeiras <iago@...volk.io>,
Yonghong Song <yhs@...com>,
Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Martin KaFai Lau <kafai@...com>,
Song Liu <songliubraving@...com>, netdev@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH bpf v1] bpf: Fix undefined behavior in narrow load handling
Commit 31fd85816dbe ("bpf: permits narrower load from bpf program
context fields") made the verifier add AND instructions to clear the
unwanted bits with a mask when doing a narrow load. The mask is
computed with
(1 << size * 8) - 1
where "size" is the size of the narrow load. When doing a 4 byte load
of a an 8 byte field the verifier shifts the literal 1 by 32 places to
the left. This results in an overflow of a signed integer, which is an
undefined behavior. Typically the computed mask was zero, so the
result of the narrow load ended up being zero too.
Cast the literal to long long to avoid overflows. Note that narrow
load of the 4 byte fields does not have the undefined behavior,
because the load size can only be either 1 or 2 bytes, so shifting 1
by 8 or 16 places will not overflow it. And reading 4 bytes would not
be a narrow load of a 4 bytes field.
Reviewed-by: Alban Crequy <alban@...volk.io>
Reviewed-by: Iago López Galeiras <iago@...volk.io>
Fixes: 31fd85816dbe ("bpf: permits narrower load from bpf program context fields")
Cc: Yonghong Song <yhs@...com>
Signed-off-by: Krzesimir Nowak <krzesimir@...volk.io>
---
kernel/bpf/verifier.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 09d5d972c9ff..950fac024fbb 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -7296,7 +7296,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
insn->dst_reg,
shift);
insn_buf[cnt++] = BPF_ALU64_IMM(BPF_AND, insn->dst_reg,
- (1 << size * 8) - 1);
+ (1ULL << size * 8) - 1);
}
}
--
2.20.1
Powered by blists - more mailing lists