[PATCH 1/2] bpf: Restrict bpf when kernel lockdown is in confidentiality mode

Tyler Hicks tyhicks at canonical.com
Thu Feb 20 00:04:25 UTC 2020


From: David Howells <dhowells at redhat.com>

BugLink: https://bugs.launchpad.net/bugs/1863234

bpf_read() and bpf_read_str() could potentially be abused to (eg) allow
private keys in kernel memory to be leaked. Disable them if the kernel
has been locked down in confidentiality mode.

Suggested-by: Alexei Starovoitov <alexei.starovoitov at gmail.com>
Signed-off-by: Matthew Garrett <mjg59 at google.com>
Reviewed-by: Kees Cook <keescook at chromium.org>
cc: netdev at vger.kernel.org
cc: Chun-Yi Lee <jlee at suse.com>
cc: Alexei Starovoitov <alexei.starovoitov at gmail.com>
Cc: Daniel Borkmann <daniel at iogearbox.net>
Signed-off-by: James Morris <jmorris at namei.org>

(backported from commit 9d1f8be5cf42b497a3bddf1d523f2bb142e9318c)
[tyhicks: Backport to 5.0:
 - Use kernel_is_locked_down() as the upstream Lockdown LSM is not
   available]
Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---
 kernel/trace/bpf_trace.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 91f636e28d37..eb9bd52a0d30 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -137,8 +137,14 @@ BPF_CALL_3(bpf_probe_read, void *, dst, u32, size, const void *, unsafe_ptr)
 {
 	int ret;
 
+	if (kernel_is_locked_down("BPF")) {
+		ret = -EPERM;
+		goto out;
+	}
+
 	ret = probe_kernel_read(dst, unsafe_ptr, size);
 	if (unlikely(ret < 0))
+out:
 		memset(dst, 0, size);
 
 	return ret;
@@ -573,6 +579,11 @@ BPF_CALL_3(bpf_probe_read_str, void *, dst, u32, size,
 {
 	int ret;
 
+	if (kernel_is_locked_down("BPF")) {
+		ret = -EPERM;
+		goto out;
+	}
+
 	/*
 	 * The strncpy_from_unsafe() call will likely not fill the entire
 	 * buffer, but that's okay in this circumstance as we're probing
@@ -584,6 +595,7 @@ BPF_CALL_3(bpf_probe_read_str, void *, dst, u32, size,
 	 */
 	ret = strncpy_from_unsafe(dst, unsafe_ptr, size);
 	if (unlikely(ret < 0))
+out:
 		memset(dst, 0, size);
 
 	return ret;
-- 
2.17.1




More information about the kernel-team mailing list