* [RFC bpf-next 0/2] bpf: sign bpf programs
@ 2021-10-12 19:00 Matteo Croce
2021-10-12 19:00 ` [RFC bpf-next 1/2] bpf: add signature to eBPF instructions Matteo Croce
2021-10-12 19:00 ` [RFC bpf-next 2/2] bpftool: add signature in skeleton Matteo Croce
0 siblings, 2 replies; 10+ messages in thread
From: Matteo Croce @ 2021-10-12 19:00 UTC (permalink / raw)
To: bpf
Cc: linux-kernel, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Arnaldo Carvalho de Melo, Luca Boccassi,
David S. Miller
From: Matteo Croce <mcroce@microsoft.com>
Add a field in bpf_attr which contains a signature for the eBPF instructions.
The signature is validated bpf_prog_load() in a similar way as kernel modules
are checked in load_module().
This only works with CO-RE programs.
The signature is generated by bpftool and embedded into the light skeleton
along with the instructions.
The bpftool crypto code is based on sign-file, supports the same interface,
and is compiled only if libcrypto is available, to avoid potential breaks.
Possible improvements:
- Add a knob which makes the signature check mandatory,
similarly to CONFIG_MODULE_SIG_FORCE
- Add a dedicate key_being_used_for type instead of using
VERIFYING_MODULE_SIGNATURE, e.g. VERIFYING_BPF_SIGNATURE
This depends on the kernel side co-re relocation[1].
[1] https://lore.kernel.org/bpf/20210917215721.43491-1-alexei.starovoitov@gmail.com/
Matteo Croce (2):
bpf: add signature to eBPF instructions
bpftool: add signature in skeleton
include/uapi/linux/bpf.h | 2 +
kernel/bpf/syscall.c | 33 ++++-
tools/bpf/bpftool/Makefile | 14 ++-
tools/bpf/bpftool/gen.c | 33 +++++
tools/bpf/bpftool/main.c | 28 +++++
tools/bpf/bpftool/main.h | 7 ++
tools/bpf/bpftool/sign.c | 217 +++++++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 2 +
tools/lib/bpf/skel_internal.h | 4 +
9 files changed, 336 insertions(+), 4 deletions(-)
create mode 100644 tools/bpf/bpftool/sign.c
--
2.33.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC bpf-next 1/2] bpf: add signature to eBPF instructions
2021-10-12 19:00 [RFC bpf-next 0/2] bpf: sign bpf programs Matteo Croce
@ 2021-10-12 19:00 ` Matteo Croce
2021-10-13 2:37 ` kernel test robot
` (4 more replies)
2021-10-12 19:00 ` [RFC bpf-next 2/2] bpftool: add signature in skeleton Matteo Croce
1 sibling, 5 replies; 10+ messages in thread
From: Matteo Croce @ 2021-10-12 19:00 UTC (permalink / raw)
To: bpf
Cc: linux-kernel, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Arnaldo Carvalho de Melo, Luca Boccassi,
David S. Miller
From: Matteo Croce <mcroce@microsoft.com>
When loading a BPF program, pass a signature which is used to validate
the instructions.
The signature type is the same used to validate the kernel modules.
Signed-off-by: Matteo Croce <mcroce@microsoft.com>
---
include/uapi/linux/bpf.h | 2 ++
kernel/bpf/syscall.c | 33 ++++++++++++++++++++++++++++++++-
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index c2b8857b8a1c..b9d259f26e92 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1336,6 +1336,8 @@ union bpf_attr {
};
__u32 :32; /* pad */
__aligned_u64 fd_array; /* array of FDs */
+ __aligned_u64 signature; /* instruction's signature */
+ __u32 sig_len; /* signature size */
};
struct { /* anonymous struct used by BPF_OBJ_* commands */
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 3c349b244a28..5589f655033d 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -31,6 +31,8 @@
#include <linux/bpf-netns.h>
#include <linux/rcupdate_trace.h>
#include <linux/memcontrol.h>
+#include <linux/verification.h>
+#include <linux/module_signature.h>
#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
(map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \
@@ -2156,7 +2158,7 @@ static bool is_perfmon_prog_type(enum bpf_prog_type prog_type)
}
/* last field in 'union bpf_attr' used by this command */
-#define BPF_PROG_LOAD_LAST_FIELD fd_array
+#define BPF_PROG_LOAD_LAST_FIELD sig_len
static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr)
{
@@ -2274,6 +2276,35 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr)
bpf_prog_insn_size(prog)) != 0)
goto free_prog_sec;
+ if (attr->sig_len) {
+ char *signature;
+
+ signature = kmalloc(attr->sig_len, GFP_USER);
+ if (!signature) {
+ err = -ENOMEM;
+ goto free_prog_sec;
+ }
+
+ if (copy_from_user(signature, (char *)attr->signature, attr->sig_len)) {
+ err = -EFAULT;
+ kfree(signature);
+ goto free_prog_sec;
+ }
+
+ err = verify_pkcs7_signature(prog->insns,
+ prog->len * sizeof(struct bpf_insn),
+ signature, attr->sig_len,
+ VERIFY_USE_SECONDARY_KEYRING,
+ VERIFYING_MODULE_SIGNATURE,
+ NULL, NULL);
+ kfree(signature);
+
+ if (err) {
+ printk("verify_pkcs7_signature(): %pe\n", (void*)(uintptr_t)err);
+ goto free_prog_sec;
+ }
+ }
+
prog->orig_prog = NULL;
prog->jited = 0;
--
2.33.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC bpf-next 2/2] bpftool: add signature in skeleton
2021-10-12 19:00 [RFC bpf-next 0/2] bpf: sign bpf programs Matteo Croce
2021-10-12 19:00 ` [RFC bpf-next 1/2] bpf: add signature to eBPF instructions Matteo Croce
@ 2021-10-12 19:00 ` Matteo Croce
1 sibling, 0 replies; 10+ messages in thread
From: Matteo Croce @ 2021-10-12 19:00 UTC (permalink / raw)
To: bpf
Cc: linux-kernel, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Arnaldo Carvalho de Melo, Luca Boccassi,
David S. Miller
From: Matteo Croce <mcroce@microsoft.com>
When generating the skeleton, allow to add a signature.
The signature will be passed to the kernel in the newly added field.
As in sign-file, allow specifing "pkcs11:..." as key file, to use the
openssl engine.
Still as in sign-file, read the environment variable KBUILD_SIGN_PIN.
Signed-off-by: Matteo Croce <mcroce@microsoft.com>
---
tools/bpf/bpftool/Makefile | 14 ++-
tools/bpf/bpftool/gen.c | 33 +++++
tools/bpf/bpftool/main.c | 28 +++++
tools/bpf/bpftool/main.h | 7 ++
tools/bpf/bpftool/sign.c | 217 +++++++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 2 +
tools/lib/bpf/skel_internal.h | 4 +
7 files changed, 302 insertions(+), 3 deletions(-)
create mode 100644 tools/bpf/bpftool/sign.c
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index 1fcf5b01a193..b67d6e0b9067 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -78,9 +78,9 @@ RM ?= rm -f
FEATURE_USER = .bpftool
FEATURE_TESTS = libbfd disassembler-four-args reallocarray zlib libcap \
- clang-bpf-co-re
+ clang-bpf-co-re libcrypto
FEATURE_DISPLAY = libbfd disassembler-four-args zlib libcap \
- clang-bpf-co-re
+ clang-bpf-co-re libcrypto
check_feat := 1
NON_CHECK_FEAT_TARGETS := clean uninstall doc doc-clean doc-install doc-uninstall
@@ -113,6 +113,11 @@ CFLAGS += -DUSE_LIBCAP
LIBS += -lcap
endif
+ifeq ($(feature-libcrypto), 1)
+CFLAGS_SSL := -DUSE_SIGN
+LIBS += -lssl -lcrypto
+endif
+
include $(wildcard $(OUTPUT)*.d)
all: $(OUTPUT)bpftool
@@ -120,6 +125,9 @@ all: $(OUTPUT)bpftool
BFD_SRCS = jit_disasm.c
SRCS = $(filter-out $(BFD_SRCS),$(wildcard *.c))
+ifneq ($(feature-libcrypto), 1)
+SRCS := $(filter-out sign.c,$(SRCS))
+endif
ifeq ($(feature-libbfd),1)
LIBS += -lbfd -ldl -lopcodes
@@ -202,7 +210,7 @@ $(BOOTSTRAP_OUTPUT)%.o: %.c | $(BOOTSTRAP_OUTPUT)
$(QUIET_CC)$(HOSTCC) $(CFLAGS) -c -MMD -o $@ $<
$(OUTPUT)%.o: %.c
- $(QUIET_CC)$(CC) $(CFLAGS) -c -MMD -o $@ $<
+ $(QUIET_CC)$(CC) $(CFLAGS) $(CFLAGS_SSL) -c -MMD -o $@ $<
feature-detect-clean:
$(call QUIET_CLEAN, feature-detect)
diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c
index cc835859465b..2551fe90dc89 100644
--- a/tools/bpf/bpftool/gen.c
+++ b/tools/bpf/bpftool/gen.c
@@ -434,6 +434,10 @@ static int gen_trace(struct bpf_object *obj, const char *obj_name, const char *h
DECLARE_LIBBPF_OPTS(gen_loader_opts, opts);
struct bpf_map *map;
int err = 0;
+#ifdef USE_SIGN
+ char *signature = NULL;
+ int sig_len = 0;
+#endif
err = bpf_object__gen_loader(obj, &opts);
if (err)
@@ -453,6 +457,19 @@ static int gen_trace(struct bpf_object *obj, const char *obj_name, const char *h
* are populated with the loader program.
*/
+#ifdef USE_SIGN
+ if (sign_bpf) {
+ sig_len = sign(sign_hash, sign_key, sign_cert,
+ opts.insns, opts.insns_sz,
+ (unsigned char **)&signature);
+ if (sig_len <= 0) {
+ p_err("failed to sign instructions");
+ err = -EINVAL;
+ goto out;
+ }
+ }
+#endif
+
/* finish generating 'struct skel' */
codegen("\
\n\
@@ -537,6 +554,18 @@ static int gen_trace(struct bpf_object *obj, const char *obj_name, const char *h
",
opts.insns_sz);
print_hex(opts.insns, opts.insns_sz);
+#ifdef USE_SIGN
+ if (sign_bpf) {
+ codegen("\
+ \n\
+ \"; \n\
+ opts.sig_sz = %d; \n\
+ opts.signature = (void *)\"\\ \n\
+ ",
+ sig_len);
+ print_hex(signature, sig_len);
+ }
+#endif
codegen("\
\n\
\"; \n\
@@ -1037,6 +1066,10 @@ static int do_help(int argc, char **argv)
" %1$s %2$s help\n"
"\n"
" " HELP_SPEC_OPTIONS " |\n"
+#ifdef USE_SIGN
+ " {-s|--sign} | {-H|--hash} |\n"
+ " {-c|--cert} | {-k|--key} |\n"
+#endif
" {-L|--use-loader} }\n"
"",
bin_name, "gen");
diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
index 02eaaf065f65..4e70b89c5b22 100644
--- a/tools/bpf/bpftool/main.c
+++ b/tools/bpf/bpftool/main.c
@@ -30,6 +30,10 @@ bool block_mount;
bool verifier_logs;
bool relaxed_maps;
bool use_loader;
+bool sign_bpf;
+const char *sign_hash;
+const char *sign_cert;
+const char *sign_key;
struct btf *base_btf;
struct pinned_obj_table prog_table;
struct pinned_obj_table map_table;
@@ -398,6 +402,12 @@ int main(int argc, char **argv)
{ "debug", no_argument, NULL, 'd' },
{ "use-loader", no_argument, NULL, 'L' },
{ "base-btf", required_argument, NULL, 'B' },
+#ifdef USE_SIGN
+ { "sign", no_argument, NULL, 's' },
+ { "hash", required_argument, NULL, 'H' },
+ { "cert", required_argument, NULL, 'c' },
+ { "key", required_argument, NULL, 'k' },
+#endif
{ 0 }
};
int opt, ret;
@@ -414,7 +424,11 @@ int main(int argc, char **argv)
hash_init(link_table.table);
opterr = 0;
+#ifdef USE_SIGN
+ while ((opt = getopt_long(argc, argv, "VhpjfLmndB:sH:c:k:",
+#else
while ((opt = getopt_long(argc, argv, "VhpjfLmndB:",
+#endif
options, NULL)) >= 0) {
switch (opt) {
case 'V':
@@ -460,6 +474,20 @@ int main(int argc, char **argv)
case 'L':
use_loader = true;
break;
+#ifdef USE_SIGN
+ case 's':
+ sign_bpf = true;
+ break;
+ case 'H':
+ sign_hash = optarg;
+ break;
+ case 'c':
+ sign_cert = optarg;
+ break;
+ case 'k':
+ sign_key = optarg;
+ break;
+#endif
default:
p_err("unrecognized option '%s'", argv[optind - 1]);
if (json_output)
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
index 90caa42aac4c..78742720447f 100644
--- a/tools/bpf/bpftool/main.h
+++ b/tools/bpf/bpftool/main.h
@@ -90,6 +90,10 @@ extern bool block_mount;
extern bool verifier_logs;
extern bool relaxed_maps;
extern bool use_loader;
+extern bool sign_bpf;
+extern const char *sign_hash;
+extern const char *sign_cert;
+extern const char *sign_key;
extern struct btf *base_btf;
extern struct pinned_obj_table prog_table;
extern struct pinned_obj_table map_table;
@@ -259,4 +263,7 @@ int do_filter_dump(struct tcmsg *ifinfo, struct nlattr **tb, const char *kind,
int print_all_levels(__maybe_unused enum libbpf_print_level level,
const char *format, va_list args);
+
+int sign(const char *hash_algo, const char *key_path, const char *x509_path,
+ const char *indata, int indatalen, unsigned char **outdata);
#endif
diff --git a/tools/bpf/bpftool/sign.c b/tools/bpf/bpftool/sign.c
new file mode 100644
index 000000000000..50b257a7177c
--- /dev/null
+++ b/tools/bpf/bpftool/sign.c
@@ -0,0 +1,217 @@
+/* Sign a module file using the given key and certificate.
+ *
+ * Inspired by Linux scripts/sign-file.c
+ * Copyright (C) 2021 Matteo Croce <mcroce@microsoft.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the licence, or (at your option) any later version.
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <err.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <openssl/opensslv.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/engine.h>
+#include <openssl/cms.h>
+
+#include "main.h"
+
+static const char *key_pass;
+
+static int pem_pw_cb(char *buf, int len, int w, void *v)
+{
+ int pwlen;
+
+ if (!key_pass)
+ return -1;
+
+ pwlen = strlen(key_pass);
+ if (pwlen >= len)
+ return -1;
+
+ strcpy(buf, key_pass);
+
+ /* If it's wrong, don't keep trying it. */
+ key_pass = NULL;
+
+ return pwlen;
+}
+
+static void display_openssl_errors(void)
+{
+ const char *file;
+ char buf[120];
+ int e, line;
+
+ if (!ERR_peek_error())
+ return;
+
+ while ((e = ERR_get_error_line(&file, &line))) {
+ ERR_error_string(e, buf);
+ fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line);
+ }
+}
+
+static EVP_PKEY *read_private_key(const char *key_path)
+{
+ EVP_PKEY *private_key;
+
+ if (!strncmp(key_path, "pkcs11:", 7)) {
+ ENGINE *e;
+
+ ENGINE_load_builtin_engines();
+ display_openssl_errors();
+ e = ENGINE_by_id("pkcs11");
+ if (!e)
+ return NULL;
+
+ if (!ENGINE_init(e)) {
+ display_openssl_errors();
+ return NULL;
+ }
+ display_openssl_errors();
+
+ if (key_pass)
+ if (!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0))
+ return NULL;
+ private_key = ENGINE_load_private_key(e, key_path, NULL, NULL);
+ } else {
+ BIO *b;
+
+ b = BIO_new_file(key_path, "rb");
+ if (!b)
+ return NULL;
+ private_key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, NULL);
+ BIO_free(b);
+ }
+
+ return private_key;
+}
+
+static X509 *read_x509(const char *x509_path)
+{
+ unsigned char buf[2];
+ X509 *x509 = NULL;
+ BIO *b;
+ int n;
+
+ b = BIO_new_file(x509_path, "rb");
+ if (!b) {
+ display_openssl_errors();
+ return NULL;
+ }
+
+ /* Look at the first two bytes of the file to determine the encoding */
+ n = BIO_read(b, buf, 2);
+ if (n != 2) {
+ if (BIO_should_retry(b))
+ fprintf(stderr, "%s: Read wanted retry\n", x509_path);
+ if (n >= 0)
+ fprintf(stderr, "%s: Short read\n", x509_path);
+ display_openssl_errors();
+ goto out_free;
+ }
+
+ if (BIO_reset(b)) {
+ display_openssl_errors();
+ goto out_free;
+ }
+
+ if (buf[0] == 0x30 && buf[1] >= 0x81 && buf[1] <= 0x84)
+ /* Assume raw DER encoded X.509 */
+ x509 = d2i_X509_bio(b, NULL);
+ else
+ /* Assume PEM encoded X.509 */
+ x509 = PEM_read_bio_X509(b, NULL, NULL, NULL);
+
+ if (!x509)
+ display_openssl_errors();
+
+out_free:
+ BIO_free(b);
+
+ return x509;
+}
+
+int sign(const char *hash_algo, const char *key_path, const char *x509_path,
+ const char *indata, int indatalen, unsigned char **outdata)
+{
+ CMS_ContentInfo *cms = NULL;
+ const EVP_MD *digest_algo;
+ EVP_PKEY *private_key;
+ X509 *x509;
+ BIO *bm;
+
+ OpenSSL_add_all_algorithms();
+ ERR_load_crypto_strings();
+ ERR_clear_error();
+
+ key_pass = getenv("KBUILD_SIGN_PIN");
+
+ /* Open the module file */
+ bm = BIO_new_mem_buf(indata, indatalen);
+ if (!bm) {
+ display_openssl_errors();
+ return -1;
+ }
+
+ /* Read the private key and the X.509 cert the PKCS#7 message
+ * will point to.
+ */
+ private_key = read_private_key(key_path);
+ if (!private_key)
+ goto out_free;
+
+ x509 = read_x509(x509_path);
+ if (!x509)
+ goto out_free;
+
+ /* Digest the module data. */
+ OpenSSL_add_all_digests();
+ display_openssl_errors();
+
+ digest_algo = EVP_get_digestbyname(hash_algo);
+ if (!digest_algo) {
+ display_openssl_errors();
+ goto out_free;
+ }
+
+ /* Load the signature message from the digest buffer. */
+ cms = CMS_sign(NULL, NULL, NULL, NULL, CMS_NOCERTS | CMS_PARTIAL |
+ CMS_BINARY | CMS_DETACHED | CMS_STREAM);
+ if (!cms) {
+ display_openssl_errors();
+ goto out_free;
+ }
+
+ if (!CMS_add1_signer(cms, x509, private_key, digest_algo,
+ CMS_NOCERTS | CMS_BINARY | CMS_NOSMIMECAP |
+ CMS_NOATTR)) {
+ display_openssl_errors();
+ goto out_free;
+ }
+
+ if (CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) < 0)
+ display_openssl_errors();
+
+out_free:
+ BIO_free(bm);
+
+ if (!cms)
+ return -1;
+
+ return i2d_CMS_ContentInfo(cms, outdata);
+}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index c2b8857b8a1c..b9d259f26e92 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -1336,6 +1336,8 @@ union bpf_attr {
};
__u32 :32; /* pad */
__aligned_u64 fd_array; /* array of FDs */
+ __aligned_u64 signature; /* instruction's signature */
+ __u32 sig_len; /* signature size */
};
struct { /* anonymous struct used by BPF_OBJ_* commands */
diff --git a/tools/lib/bpf/skel_internal.h b/tools/lib/bpf/skel_internal.h
index 9cf66702fa8d..1ef2df16f90c 100644
--- a/tools/lib/bpf/skel_internal.h
+++ b/tools/lib/bpf/skel_internal.h
@@ -42,8 +42,10 @@ struct bpf_load_and_run_opts {
struct bpf_loader_ctx *ctx;
const void *data;
const void *insns;
+ const void *signature;
__u32 data_sz;
__u32 insns_sz;
+ __u32 sig_sz;
const char *errstr;
};
@@ -84,6 +86,8 @@ static inline int bpf_load_and_run(struct bpf_load_and_run_opts *opts)
attr.prog_type = BPF_PROG_TYPE_SYSCALL;
attr.insns = (long) opts->insns;
attr.insn_cnt = opts->insns_sz / sizeof(struct bpf_insn);
+ attr.signature = (long) opts->signature;
+ attr.sig_len = opts->sig_sz;
attr.license = (long) "Dual BSD/GPL";
memcpy(attr.prog_name, "__loader.prog", sizeof("__loader.prog"));
attr.fd_array = (long) &map_fd;
--
2.33.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [RFC bpf-next 1/2] bpf: add signature to eBPF instructions
2021-10-12 19:00 ` [RFC bpf-next 1/2] bpf: add signature to eBPF instructions Matteo Croce
@ 2021-10-13 2:37 ` kernel test robot
2021-10-13 3:13 ` kernel test robot
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2021-10-13 2:37 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 10337 bytes --]
Hi Matteo,
[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on bpf-next/master]
url: https://github.com/0day-ci/linux/commits/Matteo-Croce/bpf-sign-bpf-programs/20211013-030207
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
config: sparc64-randconfig-s032-20211012 (attached as .config)
compiler: sparc64-linux-gcc (GCC) 11.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-dirty
# https://github.com/0day-ci/linux/commit/45c21d28e868dac39e5267e2e2b6f4e35f86b661
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Matteo-Croce/bpf-sign-bpf-programs/20211013-030207
git checkout 45c21d28e868dac39e5267e2e2b6f4e35f86b661
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=sparc64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
>> kernel/bpf/syscall.c:2288:48: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void const [noderef] __user *from @@ got char * @@
kernel/bpf/syscall.c:2288:48: sparse: expected void const [noderef] __user *from
kernel/bpf/syscall.c:2288:48: sparse: got char *
kernel/bpf/syscall.c: note: in included file (through include/linux/bpf.h):
include/linux/bpfptr.h:52:47: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast from non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast from non-scalar
include/linux/bpfptr.h:81:43: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:81:43: sparse: sparse: cast from non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast from non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast from non-scalar
vim +2288 kernel/bpf/syscall.c
2162
2163 static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr)
2164 {
2165 enum bpf_prog_type type = attr->prog_type;
2166 struct bpf_prog *prog, *dst_prog = NULL;
2167 struct btf *attach_btf = NULL;
2168 int err;
2169 char license[128];
2170 bool is_gpl;
2171
2172 if (CHECK_ATTR(BPF_PROG_LOAD))
2173 return -EINVAL;
2174
2175 if (attr->prog_flags & ~(BPF_F_STRICT_ALIGNMENT |
2176 BPF_F_ANY_ALIGNMENT |
2177 BPF_F_TEST_STATE_FREQ |
2178 BPF_F_SLEEPABLE |
2179 BPF_F_TEST_RND_HI32))
2180 return -EINVAL;
2181
2182 if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) &&
2183 (attr->prog_flags & BPF_F_ANY_ALIGNMENT) &&
2184 !bpf_capable())
2185 return -EPERM;
2186
2187 /* copy eBPF program license from user space */
2188 if (strncpy_from_bpfptr(license,
2189 make_bpfptr(attr->license, uattr.is_kernel),
2190 sizeof(license) - 1) < 0)
2191 return -EFAULT;
2192 license[sizeof(license) - 1] = 0;
2193
2194 /* eBPF programs must be GPL compatible to use GPL-ed functions */
2195 is_gpl = license_is_gpl_compatible(license);
2196
2197 if (attr->insn_cnt == 0 ||
2198 attr->insn_cnt > (bpf_capable() ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS))
2199 return -E2BIG;
2200 if (type != BPF_PROG_TYPE_SOCKET_FILTER &&
2201 type != BPF_PROG_TYPE_CGROUP_SKB &&
2202 !bpf_capable())
2203 return -EPERM;
2204
2205 if (is_net_admin_prog_type(type) && !capable(CAP_NET_ADMIN) && !capable(CAP_SYS_ADMIN))
2206 return -EPERM;
2207 if (is_perfmon_prog_type(type) && !perfmon_capable())
2208 return -EPERM;
2209
2210 /* attach_prog_fd/attach_btf_obj_fd can specify fd of either bpf_prog
2211 * or btf, we need to check which one it is
2212 */
2213 if (attr->attach_prog_fd) {
2214 dst_prog = bpf_prog_get(attr->attach_prog_fd);
2215 if (IS_ERR(dst_prog)) {
2216 dst_prog = NULL;
2217 attach_btf = btf_get_by_fd(attr->attach_btf_obj_fd);
2218 if (IS_ERR(attach_btf))
2219 return -EINVAL;
2220 if (!btf_is_kernel(attach_btf)) {
2221 /* attaching through specifying bpf_prog's BTF
2222 * objects directly might be supported eventually
2223 */
2224 btf_put(attach_btf);
2225 return -ENOTSUPP;
2226 }
2227 }
2228 } else if (attr->attach_btf_id) {
2229 /* fall back to vmlinux BTF, if BTF type ID is specified */
2230 attach_btf = bpf_get_btf_vmlinux();
2231 if (IS_ERR(attach_btf))
2232 return PTR_ERR(attach_btf);
2233 if (!attach_btf)
2234 return -EINVAL;
2235 btf_get(attach_btf);
2236 }
2237
2238 bpf_prog_load_fixup_attach_type(attr);
2239 if (bpf_prog_load_check_attach(type, attr->expected_attach_type,
2240 attach_btf, attr->attach_btf_id,
2241 dst_prog)) {
2242 if (dst_prog)
2243 bpf_prog_put(dst_prog);
2244 if (attach_btf)
2245 btf_put(attach_btf);
2246 return -EINVAL;
2247 }
2248
2249 /* plain bpf_prog allocation */
2250 prog = bpf_prog_alloc(bpf_prog_size(attr->insn_cnt), GFP_USER);
2251 if (!prog) {
2252 if (dst_prog)
2253 bpf_prog_put(dst_prog);
2254 if (attach_btf)
2255 btf_put(attach_btf);
2256 return -ENOMEM;
2257 }
2258
2259 prog->expected_attach_type = attr->expected_attach_type;
2260 prog->aux->attach_btf = attach_btf;
2261 prog->aux->attach_btf_id = attr->attach_btf_id;
2262 prog->aux->dst_prog = dst_prog;
2263 prog->aux->offload_requested = !!attr->prog_ifindex;
2264 prog->aux->sleepable = attr->prog_flags & BPF_F_SLEEPABLE;
2265
2266 err = security_bpf_prog_alloc(prog->aux);
2267 if (err)
2268 goto free_prog;
2269
2270 prog->aux->user = get_current_user();
2271 prog->len = attr->insn_cnt;
2272
2273 err = -EFAULT;
2274 if (copy_from_bpfptr(prog->insns,
2275 make_bpfptr(attr->insns, uattr.is_kernel),
2276 bpf_prog_insn_size(prog)) != 0)
2277 goto free_prog_sec;
2278
2279 if (attr->sig_len) {
2280 char *signature;
2281
2282 signature = kmalloc(attr->sig_len, GFP_USER);
2283 if (!signature) {
2284 err = -ENOMEM;
2285 goto free_prog_sec;
2286 }
2287
> 2288 if (copy_from_user(signature, (char *)attr->signature, attr->sig_len)) {
2289 err = -EFAULT;
2290 kfree(signature);
2291 goto free_prog_sec;
2292 }
2293
2294 err = verify_pkcs7_signature(prog->insns,
2295 prog->len * sizeof(struct bpf_insn),
2296 signature, attr->sig_len,
2297 VERIFY_USE_SECONDARY_KEYRING,
2298 VERIFYING_MODULE_SIGNATURE,
2299 NULL, NULL);
2300 kfree(signature);
2301
2302 if (err) {
2303 printk("verify_pkcs7_signature(): %pe\n", (void*)(uintptr_t)err);
2304 goto free_prog_sec;
2305 }
2306 }
2307
2308 prog->orig_prog = NULL;
2309 prog->jited = 0;
2310
2311 atomic64_set(&prog->aux->refcnt, 1);
2312 prog->gpl_compatible = is_gpl ? 1 : 0;
2313
2314 if (bpf_prog_is_dev_bound(prog->aux)) {
2315 err = bpf_prog_offload_init(prog, attr);
2316 if (err)
2317 goto free_prog_sec;
2318 }
2319
2320 /* find program type: socket_filter vs tracing_filter */
2321 err = find_prog_type(type, prog);
2322 if (err < 0)
2323 goto free_prog_sec;
2324
2325 prog->aux->load_time = ktime_get_boottime_ns();
2326 err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name,
2327 sizeof(attr->prog_name));
2328 if (err < 0)
2329 goto free_prog_sec;
2330
2331 /* run eBPF verifier */
2332 err = bpf_check(&prog, attr, uattr);
2333 if (err < 0)
2334 goto free_used_maps;
2335
2336 prog = bpf_prog_select_runtime(prog, &err);
2337 if (err < 0)
2338 goto free_used_maps;
2339
2340 err = bpf_prog_alloc_id(prog);
2341 if (err)
2342 goto free_used_maps;
2343
2344 /* Upon success of bpf_prog_alloc_id(), the BPF prog is
2345 * effectively publicly exposed. However, retrieving via
2346 * bpf_prog_get_fd_by_id() will take another reference,
2347 * therefore it cannot be gone underneath us.
2348 *
2349 * Only for the time /after/ successful bpf_prog_new_fd()
2350 * and before returning to userspace, we might just hold
2351 * one reference and any parallel close on that fd could
2352 * rip everything out. Hence, below notifications must
2353 * happen before bpf_prog_new_fd().
2354 *
2355 * Also, any failure handling from this point onwards must
2356 * be using bpf_prog_put() given the program is exposed.
2357 */
2358 bpf_prog_kallsyms_add(prog);
2359 perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_LOAD, 0);
2360 bpf_audit_prog(prog, BPF_AUDIT_LOAD);
2361
2362 err = bpf_prog_new_fd(prog);
2363 if (err < 0)
2364 bpf_prog_put(prog);
2365 return err;
2366
2367 free_used_maps:
2368 /* In case we have subprogs, we need to wait for a grace
2369 * period before we can tear down JIT memory since symbols
2370 * are already exposed under kallsyms.
2371 */
2372 __bpf_prog_put_noref(prog, prog->aux->func_cnt);
2373 return err;
2374 free_prog_sec:
2375 free_uid(prog->aux->user);
2376 security_bpf_prog_free(prog->aux);
2377 free_prog:
2378 if (prog->aux->attach_btf)
2379 btf_put(prog->aux->attach_btf);
2380 bpf_prog_free(prog);
2381 return err;
2382 }
2383
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 34805 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC bpf-next 1/2] bpf: add signature to eBPF instructions
2021-10-12 19:00 ` [RFC bpf-next 1/2] bpf: add signature to eBPF instructions Matteo Croce
2021-10-13 2:37 ` kernel test robot
@ 2021-10-13 3:13 ` kernel test robot
2021-10-13 3:36 ` kernel test robot
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2021-10-13 3:13 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 9799 bytes --]
Hi Matteo,
[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on bpf-next/master]
url: https://github.com/0day-ci/linux/commits/Matteo-Croce/bpf-sign-bpf-programs/20211013-030207
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
config: nios2-randconfig-r034-20211013 (attached as .config)
compiler: nios2-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/45c21d28e868dac39e5267e2e2b6f4e35f86b661
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Matteo-Croce/bpf-sign-bpf-programs/20211013-030207
git checkout 45c21d28e868dac39e5267e2e2b6f4e35f86b661
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=nios2
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All error/warnings (new ones prefixed by >>):
kernel/bpf/syscall.c: In function 'bpf_prog_load':
>> kernel/bpf/syscall.c:2288:47: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
2288 | if (copy_from_user(signature, (char *)attr->signature, attr->sig_len)) {
| ^
>> kernel/bpf/syscall.c:2294:23: error: implicit declaration of function 'verify_pkcs7_signature' [-Werror=implicit-function-declaration]
2294 | err = verify_pkcs7_signature(prog->insns,
| ^~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +/verify_pkcs7_signature +2294 kernel/bpf/syscall.c
2162
2163 static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr)
2164 {
2165 enum bpf_prog_type type = attr->prog_type;
2166 struct bpf_prog *prog, *dst_prog = NULL;
2167 struct btf *attach_btf = NULL;
2168 int err;
2169 char license[128];
2170 bool is_gpl;
2171
2172 if (CHECK_ATTR(BPF_PROG_LOAD))
2173 return -EINVAL;
2174
2175 if (attr->prog_flags & ~(BPF_F_STRICT_ALIGNMENT |
2176 BPF_F_ANY_ALIGNMENT |
2177 BPF_F_TEST_STATE_FREQ |
2178 BPF_F_SLEEPABLE |
2179 BPF_F_TEST_RND_HI32))
2180 return -EINVAL;
2181
2182 if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) &&
2183 (attr->prog_flags & BPF_F_ANY_ALIGNMENT) &&
2184 !bpf_capable())
2185 return -EPERM;
2186
2187 /* copy eBPF program license from user space */
2188 if (strncpy_from_bpfptr(license,
2189 make_bpfptr(attr->license, uattr.is_kernel),
2190 sizeof(license) - 1) < 0)
2191 return -EFAULT;
2192 license[sizeof(license) - 1] = 0;
2193
2194 /* eBPF programs must be GPL compatible to use GPL-ed functions */
2195 is_gpl = license_is_gpl_compatible(license);
2196
2197 if (attr->insn_cnt == 0 ||
2198 attr->insn_cnt > (bpf_capable() ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS))
2199 return -E2BIG;
2200 if (type != BPF_PROG_TYPE_SOCKET_FILTER &&
2201 type != BPF_PROG_TYPE_CGROUP_SKB &&
2202 !bpf_capable())
2203 return -EPERM;
2204
2205 if (is_net_admin_prog_type(type) && !capable(CAP_NET_ADMIN) && !capable(CAP_SYS_ADMIN))
2206 return -EPERM;
2207 if (is_perfmon_prog_type(type) && !perfmon_capable())
2208 return -EPERM;
2209
2210 /* attach_prog_fd/attach_btf_obj_fd can specify fd of either bpf_prog
2211 * or btf, we need to check which one it is
2212 */
2213 if (attr->attach_prog_fd) {
2214 dst_prog = bpf_prog_get(attr->attach_prog_fd);
2215 if (IS_ERR(dst_prog)) {
2216 dst_prog = NULL;
2217 attach_btf = btf_get_by_fd(attr->attach_btf_obj_fd);
2218 if (IS_ERR(attach_btf))
2219 return -EINVAL;
2220 if (!btf_is_kernel(attach_btf)) {
2221 /* attaching through specifying bpf_prog's BTF
2222 * objects directly might be supported eventually
2223 */
2224 btf_put(attach_btf);
2225 return -ENOTSUPP;
2226 }
2227 }
2228 } else if (attr->attach_btf_id) {
2229 /* fall back to vmlinux BTF, if BTF type ID is specified */
2230 attach_btf = bpf_get_btf_vmlinux();
2231 if (IS_ERR(attach_btf))
2232 return PTR_ERR(attach_btf);
2233 if (!attach_btf)
2234 return -EINVAL;
2235 btf_get(attach_btf);
2236 }
2237
2238 bpf_prog_load_fixup_attach_type(attr);
2239 if (bpf_prog_load_check_attach(type, attr->expected_attach_type,
2240 attach_btf, attr->attach_btf_id,
2241 dst_prog)) {
2242 if (dst_prog)
2243 bpf_prog_put(dst_prog);
2244 if (attach_btf)
2245 btf_put(attach_btf);
2246 return -EINVAL;
2247 }
2248
2249 /* plain bpf_prog allocation */
2250 prog = bpf_prog_alloc(bpf_prog_size(attr->insn_cnt), GFP_USER);
2251 if (!prog) {
2252 if (dst_prog)
2253 bpf_prog_put(dst_prog);
2254 if (attach_btf)
2255 btf_put(attach_btf);
2256 return -ENOMEM;
2257 }
2258
2259 prog->expected_attach_type = attr->expected_attach_type;
2260 prog->aux->attach_btf = attach_btf;
2261 prog->aux->attach_btf_id = attr->attach_btf_id;
2262 prog->aux->dst_prog = dst_prog;
2263 prog->aux->offload_requested = !!attr->prog_ifindex;
2264 prog->aux->sleepable = attr->prog_flags & BPF_F_SLEEPABLE;
2265
2266 err = security_bpf_prog_alloc(prog->aux);
2267 if (err)
2268 goto free_prog;
2269
2270 prog->aux->user = get_current_user();
2271 prog->len = attr->insn_cnt;
2272
2273 err = -EFAULT;
2274 if (copy_from_bpfptr(prog->insns,
2275 make_bpfptr(attr->insns, uattr.is_kernel),
2276 bpf_prog_insn_size(prog)) != 0)
2277 goto free_prog_sec;
2278
2279 if (attr->sig_len) {
2280 char *signature;
2281
2282 signature = kmalloc(attr->sig_len, GFP_USER);
2283 if (!signature) {
2284 err = -ENOMEM;
2285 goto free_prog_sec;
2286 }
2287
> 2288 if (copy_from_user(signature, (char *)attr->signature, attr->sig_len)) {
2289 err = -EFAULT;
2290 kfree(signature);
2291 goto free_prog_sec;
2292 }
2293
> 2294 err = verify_pkcs7_signature(prog->insns,
2295 prog->len * sizeof(struct bpf_insn),
2296 signature, attr->sig_len,
2297 VERIFY_USE_SECONDARY_KEYRING,
2298 VERIFYING_MODULE_SIGNATURE,
2299 NULL, NULL);
2300 kfree(signature);
2301
2302 if (err) {
2303 printk("verify_pkcs7_signature(): %pe\n", (void*)(uintptr_t)err);
2304 goto free_prog_sec;
2305 }
2306 }
2307
2308 prog->orig_prog = NULL;
2309 prog->jited = 0;
2310
2311 atomic64_set(&prog->aux->refcnt, 1);
2312 prog->gpl_compatible = is_gpl ? 1 : 0;
2313
2314 if (bpf_prog_is_dev_bound(prog->aux)) {
2315 err = bpf_prog_offload_init(prog, attr);
2316 if (err)
2317 goto free_prog_sec;
2318 }
2319
2320 /* find program type: socket_filter vs tracing_filter */
2321 err = find_prog_type(type, prog);
2322 if (err < 0)
2323 goto free_prog_sec;
2324
2325 prog->aux->load_time = ktime_get_boottime_ns();
2326 err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name,
2327 sizeof(attr->prog_name));
2328 if (err < 0)
2329 goto free_prog_sec;
2330
2331 /* run eBPF verifier */
2332 err = bpf_check(&prog, attr, uattr);
2333 if (err < 0)
2334 goto free_used_maps;
2335
2336 prog = bpf_prog_select_runtime(prog, &err);
2337 if (err < 0)
2338 goto free_used_maps;
2339
2340 err = bpf_prog_alloc_id(prog);
2341 if (err)
2342 goto free_used_maps;
2343
2344 /* Upon success of bpf_prog_alloc_id(), the BPF prog is
2345 * effectively publicly exposed. However, retrieving via
2346 * bpf_prog_get_fd_by_id() will take another reference,
2347 * therefore it cannot be gone underneath us.
2348 *
2349 * Only for the time /after/ successful bpf_prog_new_fd()
2350 * and before returning to userspace, we might just hold
2351 * one reference and any parallel close on that fd could
2352 * rip everything out. Hence, below notifications must
2353 * happen before bpf_prog_new_fd().
2354 *
2355 * Also, any failure handling from this point onwards must
2356 * be using bpf_prog_put() given the program is exposed.
2357 */
2358 bpf_prog_kallsyms_add(prog);
2359 perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_LOAD, 0);
2360 bpf_audit_prog(prog, BPF_AUDIT_LOAD);
2361
2362 err = bpf_prog_new_fd(prog);
2363 if (err < 0)
2364 bpf_prog_put(prog);
2365 return err;
2366
2367 free_used_maps:
2368 /* In case we have subprogs, we need to wait for a grace
2369 * period before we can tear down JIT memory since symbols
2370 * are already exposed under kallsyms.
2371 */
2372 __bpf_prog_put_noref(prog, prog->aux->func_cnt);
2373 return err;
2374 free_prog_sec:
2375 free_uid(prog->aux->user);
2376 security_bpf_prog_free(prog->aux);
2377 free_prog:
2378 if (prog->aux->attach_btf)
2379 btf_put(prog->aux->attach_btf);
2380 bpf_prog_free(prog);
2381 return err;
2382 }
2383
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 31072 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC bpf-next 1/2] bpf: add signature to eBPF instructions
2021-10-12 19:00 ` [RFC bpf-next 1/2] bpf: add signature to eBPF instructions Matteo Croce
2021-10-13 2:37 ` kernel test robot
2021-10-13 3:13 ` kernel test robot
@ 2021-10-13 3:36 ` kernel test robot
2021-10-13 14:35 ` kernel test robot
2021-10-24 22:35 ` kernel test robot
4 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2021-10-13 3:36 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 9287 bytes --]
Hi Matteo,
[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on bpf-next/master]
url: https://github.com/0day-ci/linux/commits/Matteo-Croce/bpf-sign-bpf-programs/20211013-030207
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
config: i386-buildonly-randconfig-r002-20211012 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
# https://github.com/0day-ci/linux/commit/45c21d28e868dac39e5267e2e2b6f4e35f86b661
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Matteo-Croce/bpf-sign-bpf-programs/20211013-030207
git checkout 45c21d28e868dac39e5267e2e2b6f4e35f86b661
# save the attached .config to linux build tree
make W=1 ARCH=i386
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
kernel/bpf/syscall.c: In function 'bpf_prog_load':
>> kernel/bpf/syscall.c:2288:33: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
2288 | if (copy_from_user(signature, (char *)attr->signature, attr->sig_len)) {
| ^
cc1: all warnings being treated as errors
vim +2288 kernel/bpf/syscall.c
2162
2163 static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr)
2164 {
2165 enum bpf_prog_type type = attr->prog_type;
2166 struct bpf_prog *prog, *dst_prog = NULL;
2167 struct btf *attach_btf = NULL;
2168 int err;
2169 char license[128];
2170 bool is_gpl;
2171
2172 if (CHECK_ATTR(BPF_PROG_LOAD))
2173 return -EINVAL;
2174
2175 if (attr->prog_flags & ~(BPF_F_STRICT_ALIGNMENT |
2176 BPF_F_ANY_ALIGNMENT |
2177 BPF_F_TEST_STATE_FREQ |
2178 BPF_F_SLEEPABLE |
2179 BPF_F_TEST_RND_HI32))
2180 return -EINVAL;
2181
2182 if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) &&
2183 (attr->prog_flags & BPF_F_ANY_ALIGNMENT) &&
2184 !bpf_capable())
2185 return -EPERM;
2186
2187 /* copy eBPF program license from user space */
2188 if (strncpy_from_bpfptr(license,
2189 make_bpfptr(attr->license, uattr.is_kernel),
2190 sizeof(license) - 1) < 0)
2191 return -EFAULT;
2192 license[sizeof(license) - 1] = 0;
2193
2194 /* eBPF programs must be GPL compatible to use GPL-ed functions */
2195 is_gpl = license_is_gpl_compatible(license);
2196
2197 if (attr->insn_cnt == 0 ||
2198 attr->insn_cnt > (bpf_capable() ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS))
2199 return -E2BIG;
2200 if (type != BPF_PROG_TYPE_SOCKET_FILTER &&
2201 type != BPF_PROG_TYPE_CGROUP_SKB &&
2202 !bpf_capable())
2203 return -EPERM;
2204
2205 if (is_net_admin_prog_type(type) && !capable(CAP_NET_ADMIN) && !capable(CAP_SYS_ADMIN))
2206 return -EPERM;
2207 if (is_perfmon_prog_type(type) && !perfmon_capable())
2208 return -EPERM;
2209
2210 /* attach_prog_fd/attach_btf_obj_fd can specify fd of either bpf_prog
2211 * or btf, we need to check which one it is
2212 */
2213 if (attr->attach_prog_fd) {
2214 dst_prog = bpf_prog_get(attr->attach_prog_fd);
2215 if (IS_ERR(dst_prog)) {
2216 dst_prog = NULL;
2217 attach_btf = btf_get_by_fd(attr->attach_btf_obj_fd);
2218 if (IS_ERR(attach_btf))
2219 return -EINVAL;
2220 if (!btf_is_kernel(attach_btf)) {
2221 /* attaching through specifying bpf_prog's BTF
2222 * objects directly might be supported eventually
2223 */
2224 btf_put(attach_btf);
2225 return -ENOTSUPP;
2226 }
2227 }
2228 } else if (attr->attach_btf_id) {
2229 /* fall back to vmlinux BTF, if BTF type ID is specified */
2230 attach_btf = bpf_get_btf_vmlinux();
2231 if (IS_ERR(attach_btf))
2232 return PTR_ERR(attach_btf);
2233 if (!attach_btf)
2234 return -EINVAL;
2235 btf_get(attach_btf);
2236 }
2237
2238 bpf_prog_load_fixup_attach_type(attr);
2239 if (bpf_prog_load_check_attach(type, attr->expected_attach_type,
2240 attach_btf, attr->attach_btf_id,
2241 dst_prog)) {
2242 if (dst_prog)
2243 bpf_prog_put(dst_prog);
2244 if (attach_btf)
2245 btf_put(attach_btf);
2246 return -EINVAL;
2247 }
2248
2249 /* plain bpf_prog allocation */
2250 prog = bpf_prog_alloc(bpf_prog_size(attr->insn_cnt), GFP_USER);
2251 if (!prog) {
2252 if (dst_prog)
2253 bpf_prog_put(dst_prog);
2254 if (attach_btf)
2255 btf_put(attach_btf);
2256 return -ENOMEM;
2257 }
2258
2259 prog->expected_attach_type = attr->expected_attach_type;
2260 prog->aux->attach_btf = attach_btf;
2261 prog->aux->attach_btf_id = attr->attach_btf_id;
2262 prog->aux->dst_prog = dst_prog;
2263 prog->aux->offload_requested = !!attr->prog_ifindex;
2264 prog->aux->sleepable = attr->prog_flags & BPF_F_SLEEPABLE;
2265
2266 err = security_bpf_prog_alloc(prog->aux);
2267 if (err)
2268 goto free_prog;
2269
2270 prog->aux->user = get_current_user();
2271 prog->len = attr->insn_cnt;
2272
2273 err = -EFAULT;
2274 if (copy_from_bpfptr(prog->insns,
2275 make_bpfptr(attr->insns, uattr.is_kernel),
2276 bpf_prog_insn_size(prog)) != 0)
2277 goto free_prog_sec;
2278
2279 if (attr->sig_len) {
2280 char *signature;
2281
2282 signature = kmalloc(attr->sig_len, GFP_USER);
2283 if (!signature) {
2284 err = -ENOMEM;
2285 goto free_prog_sec;
2286 }
2287
> 2288 if (copy_from_user(signature, (char *)attr->signature, attr->sig_len)) {
2289 err = -EFAULT;
2290 kfree(signature);
2291 goto free_prog_sec;
2292 }
2293
2294 err = verify_pkcs7_signature(prog->insns,
2295 prog->len * sizeof(struct bpf_insn),
2296 signature, attr->sig_len,
2297 VERIFY_USE_SECONDARY_KEYRING,
2298 VERIFYING_MODULE_SIGNATURE,
2299 NULL, NULL);
2300 kfree(signature);
2301
2302 if (err) {
2303 printk("verify_pkcs7_signature(): %pe\n", (void*)(uintptr_t)err);
2304 goto free_prog_sec;
2305 }
2306 }
2307
2308 prog->orig_prog = NULL;
2309 prog->jited = 0;
2310
2311 atomic64_set(&prog->aux->refcnt, 1);
2312 prog->gpl_compatible = is_gpl ? 1 : 0;
2313
2314 if (bpf_prog_is_dev_bound(prog->aux)) {
2315 err = bpf_prog_offload_init(prog, attr);
2316 if (err)
2317 goto free_prog_sec;
2318 }
2319
2320 /* find program type: socket_filter vs tracing_filter */
2321 err = find_prog_type(type, prog);
2322 if (err < 0)
2323 goto free_prog_sec;
2324
2325 prog->aux->load_time = ktime_get_boottime_ns();
2326 err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name,
2327 sizeof(attr->prog_name));
2328 if (err < 0)
2329 goto free_prog_sec;
2330
2331 /* run eBPF verifier */
2332 err = bpf_check(&prog, attr, uattr);
2333 if (err < 0)
2334 goto free_used_maps;
2335
2336 prog = bpf_prog_select_runtime(prog, &err);
2337 if (err < 0)
2338 goto free_used_maps;
2339
2340 err = bpf_prog_alloc_id(prog);
2341 if (err)
2342 goto free_used_maps;
2343
2344 /* Upon success of bpf_prog_alloc_id(), the BPF prog is
2345 * effectively publicly exposed. However, retrieving via
2346 * bpf_prog_get_fd_by_id() will take another reference,
2347 * therefore it cannot be gone underneath us.
2348 *
2349 * Only for the time /after/ successful bpf_prog_new_fd()
2350 * and before returning to userspace, we might just hold
2351 * one reference and any parallel close on that fd could
2352 * rip everything out. Hence, below notifications must
2353 * happen before bpf_prog_new_fd().
2354 *
2355 * Also, any failure handling from this point onwards must
2356 * be using bpf_prog_put() given the program is exposed.
2357 */
2358 bpf_prog_kallsyms_add(prog);
2359 perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_LOAD, 0);
2360 bpf_audit_prog(prog, BPF_AUDIT_LOAD);
2361
2362 err = bpf_prog_new_fd(prog);
2363 if (err < 0)
2364 bpf_prog_put(prog);
2365 return err;
2366
2367 free_used_maps:
2368 /* In case we have subprogs, we need to wait for a grace
2369 * period before we can tear down JIT memory since symbols
2370 * are already exposed under kallsyms.
2371 */
2372 __bpf_prog_put_noref(prog, prog->aux->func_cnt);
2373 return err;
2374 free_prog_sec:
2375 free_uid(prog->aux->user);
2376 security_bpf_prog_free(prog->aux);
2377 free_prog:
2378 if (prog->aux->attach_btf)
2379 btf_put(prog->aux->attach_btf);
2380 bpf_prog_free(prog);
2381 return err;
2382 }
2383
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 38303 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC bpf-next 1/2] bpf: add signature to eBPF instructions
2021-10-12 19:00 ` [RFC bpf-next 1/2] bpf: add signature to eBPF instructions Matteo Croce
` (2 preceding siblings ...)
2021-10-13 3:36 ` kernel test robot
@ 2021-10-13 14:35 ` kernel test robot
2021-10-24 22:35 ` kernel test robot
4 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2021-10-13 14:35 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 11053 bytes --]
Hi Matteo,
[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on bpf-next/master]
url: https://github.com/0day-ci/linux/commits/Matteo-Croce/bpf-sign-bpf-programs/20211013-030207
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
config: mips-randconfig-s031-20211013 (attached as .config)
compiler: mipsel-linux-gcc (GCC) 11.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-dirty
# https://github.com/0day-ci/linux/commit/45c21d28e868dac39e5267e2e2b6f4e35f86b661
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Matteo-Croce/bpf-sign-bpf-programs/20211013-030207
git checkout 45c21d28e868dac39e5267e2e2b6f4e35f86b661
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=mips SHELL=/bin/bash kernel/bpf/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
command-line: note: in included file:
builtin:1:9: sparse: sparse: preprocessor token __ATOMIC_ACQUIRE redefined
builtin:0:0: sparse: this was the original definition
builtin:1:9: sparse: sparse: preprocessor token __ATOMIC_SEQ_CST redefined
builtin:0:0: sparse: this was the original definition
builtin:1:9: sparse: sparse: preprocessor token __ATOMIC_ACQ_REL redefined
builtin:0:0: sparse: this was the original definition
builtin:1:9: sparse: sparse: preprocessor token __ATOMIC_RELEASE redefined
builtin:0:0: sparse: this was the original definition
kernel/bpf/syscall.c:2288:48: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void const [noderef] __user *from @@ got char * @@
kernel/bpf/syscall.c:2288:48: sparse: expected void const [noderef] __user *from
kernel/bpf/syscall.c:2288:48: sparse: got char *
kernel/bpf/syscall.c: note: in included file (through include/linux/bpf.h):
include/linux/bpfptr.h:52:47: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast from non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast from non-scalar
include/linux/bpfptr.h:81:43: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:81:43: sparse: sparse: cast from non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast from non-scalar
>> kernel/bpf/syscall.c:2288:55: sparse: sparse: non size-preserving integer to pointer cast
include/linux/bpfptr.h:52:47: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast from non-scalar
vim +2288 kernel/bpf/syscall.c
2162
2163 static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr)
2164 {
2165 enum bpf_prog_type type = attr->prog_type;
2166 struct bpf_prog *prog, *dst_prog = NULL;
2167 struct btf *attach_btf = NULL;
2168 int err;
2169 char license[128];
2170 bool is_gpl;
2171
2172 if (CHECK_ATTR(BPF_PROG_LOAD))
2173 return -EINVAL;
2174
2175 if (attr->prog_flags & ~(BPF_F_STRICT_ALIGNMENT |
2176 BPF_F_ANY_ALIGNMENT |
2177 BPF_F_TEST_STATE_FREQ |
2178 BPF_F_SLEEPABLE |
2179 BPF_F_TEST_RND_HI32))
2180 return -EINVAL;
2181
2182 if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) &&
2183 (attr->prog_flags & BPF_F_ANY_ALIGNMENT) &&
2184 !bpf_capable())
2185 return -EPERM;
2186
2187 /* copy eBPF program license from user space */
2188 if (strncpy_from_bpfptr(license,
2189 make_bpfptr(attr->license, uattr.is_kernel),
2190 sizeof(license) - 1) < 0)
2191 return -EFAULT;
2192 license[sizeof(license) - 1] = 0;
2193
2194 /* eBPF programs must be GPL compatible to use GPL-ed functions */
2195 is_gpl = license_is_gpl_compatible(license);
2196
2197 if (attr->insn_cnt == 0 ||
2198 attr->insn_cnt > (bpf_capable() ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS))
2199 return -E2BIG;
2200 if (type != BPF_PROG_TYPE_SOCKET_FILTER &&
2201 type != BPF_PROG_TYPE_CGROUP_SKB &&
2202 !bpf_capable())
2203 return -EPERM;
2204
2205 if (is_net_admin_prog_type(type) && !capable(CAP_NET_ADMIN) && !capable(CAP_SYS_ADMIN))
2206 return -EPERM;
2207 if (is_perfmon_prog_type(type) && !perfmon_capable())
2208 return -EPERM;
2209
2210 /* attach_prog_fd/attach_btf_obj_fd can specify fd of either bpf_prog
2211 * or btf, we need to check which one it is
2212 */
2213 if (attr->attach_prog_fd) {
2214 dst_prog = bpf_prog_get(attr->attach_prog_fd);
2215 if (IS_ERR(dst_prog)) {
2216 dst_prog = NULL;
2217 attach_btf = btf_get_by_fd(attr->attach_btf_obj_fd);
2218 if (IS_ERR(attach_btf))
2219 return -EINVAL;
2220 if (!btf_is_kernel(attach_btf)) {
2221 /* attaching through specifying bpf_prog's BTF
2222 * objects directly might be supported eventually
2223 */
2224 btf_put(attach_btf);
2225 return -ENOTSUPP;
2226 }
2227 }
2228 } else if (attr->attach_btf_id) {
2229 /* fall back to vmlinux BTF, if BTF type ID is specified */
2230 attach_btf = bpf_get_btf_vmlinux();
2231 if (IS_ERR(attach_btf))
2232 return PTR_ERR(attach_btf);
2233 if (!attach_btf)
2234 return -EINVAL;
2235 btf_get(attach_btf);
2236 }
2237
2238 bpf_prog_load_fixup_attach_type(attr);
2239 if (bpf_prog_load_check_attach(type, attr->expected_attach_type,
2240 attach_btf, attr->attach_btf_id,
2241 dst_prog)) {
2242 if (dst_prog)
2243 bpf_prog_put(dst_prog);
2244 if (attach_btf)
2245 btf_put(attach_btf);
2246 return -EINVAL;
2247 }
2248
2249 /* plain bpf_prog allocation */
2250 prog = bpf_prog_alloc(bpf_prog_size(attr->insn_cnt), GFP_USER);
2251 if (!prog) {
2252 if (dst_prog)
2253 bpf_prog_put(dst_prog);
2254 if (attach_btf)
2255 btf_put(attach_btf);
2256 return -ENOMEM;
2257 }
2258
2259 prog->expected_attach_type = attr->expected_attach_type;
2260 prog->aux->attach_btf = attach_btf;
2261 prog->aux->attach_btf_id = attr->attach_btf_id;
2262 prog->aux->dst_prog = dst_prog;
2263 prog->aux->offload_requested = !!attr->prog_ifindex;
2264 prog->aux->sleepable = attr->prog_flags & BPF_F_SLEEPABLE;
2265
2266 err = security_bpf_prog_alloc(prog->aux);
2267 if (err)
2268 goto free_prog;
2269
2270 prog->aux->user = get_current_user();
2271 prog->len = attr->insn_cnt;
2272
2273 err = -EFAULT;
2274 if (copy_from_bpfptr(prog->insns,
2275 make_bpfptr(attr->insns, uattr.is_kernel),
2276 bpf_prog_insn_size(prog)) != 0)
2277 goto free_prog_sec;
2278
2279 if (attr->sig_len) {
2280 char *signature;
2281
2282 signature = kmalloc(attr->sig_len, GFP_USER);
2283 if (!signature) {
2284 err = -ENOMEM;
2285 goto free_prog_sec;
2286 }
2287
> 2288 if (copy_from_user(signature, (char *)attr->signature, attr->sig_len)) {
2289 err = -EFAULT;
2290 kfree(signature);
2291 goto free_prog_sec;
2292 }
2293
2294 err = verify_pkcs7_signature(prog->insns,
2295 prog->len * sizeof(struct bpf_insn),
2296 signature, attr->sig_len,
2297 VERIFY_USE_SECONDARY_KEYRING,
2298 VERIFYING_MODULE_SIGNATURE,
2299 NULL, NULL);
2300 kfree(signature);
2301
2302 if (err) {
2303 printk("verify_pkcs7_signature(): %pe\n", (void*)(uintptr_t)err);
2304 goto free_prog_sec;
2305 }
2306 }
2307
2308 prog->orig_prog = NULL;
2309 prog->jited = 0;
2310
2311 atomic64_set(&prog->aux->refcnt, 1);
2312 prog->gpl_compatible = is_gpl ? 1 : 0;
2313
2314 if (bpf_prog_is_dev_bound(prog->aux)) {
2315 err = bpf_prog_offload_init(prog, attr);
2316 if (err)
2317 goto free_prog_sec;
2318 }
2319
2320 /* find program type: socket_filter vs tracing_filter */
2321 err = find_prog_type(type, prog);
2322 if (err < 0)
2323 goto free_prog_sec;
2324
2325 prog->aux->load_time = ktime_get_boottime_ns();
2326 err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name,
2327 sizeof(attr->prog_name));
2328 if (err < 0)
2329 goto free_prog_sec;
2330
2331 /* run eBPF verifier */
2332 err = bpf_check(&prog, attr, uattr);
2333 if (err < 0)
2334 goto free_used_maps;
2335
2336 prog = bpf_prog_select_runtime(prog, &err);
2337 if (err < 0)
2338 goto free_used_maps;
2339
2340 err = bpf_prog_alloc_id(prog);
2341 if (err)
2342 goto free_used_maps;
2343
2344 /* Upon success of bpf_prog_alloc_id(), the BPF prog is
2345 * effectively publicly exposed. However, retrieving via
2346 * bpf_prog_get_fd_by_id() will take another reference,
2347 * therefore it cannot be gone underneath us.
2348 *
2349 * Only for the time /after/ successful bpf_prog_new_fd()
2350 * and before returning to userspace, we might just hold
2351 * one reference and any parallel close on that fd could
2352 * rip everything out. Hence, below notifications must
2353 * happen before bpf_prog_new_fd().
2354 *
2355 * Also, any failure handling from this point onwards must
2356 * be using bpf_prog_put() given the program is exposed.
2357 */
2358 bpf_prog_kallsyms_add(prog);
2359 perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_LOAD, 0);
2360 bpf_audit_prog(prog, BPF_AUDIT_LOAD);
2361
2362 err = bpf_prog_new_fd(prog);
2363 if (err < 0)
2364 bpf_prog_put(prog);
2365 return err;
2366
2367 free_used_maps:
2368 /* In case we have subprogs, we need to wait for a grace
2369 * period before we can tear down JIT memory since symbols
2370 * are already exposed under kallsyms.
2371 */
2372 __bpf_prog_put_noref(prog, prog->aux->func_cnt);
2373 return err;
2374 free_prog_sec:
2375 free_uid(prog->aux->user);
2376 security_bpf_prog_free(prog->aux);
2377 free_prog:
2378 if (prog->aux->attach_btf)
2379 btf_put(prog->aux->attach_btf);
2380 bpf_prog_free(prog);
2381 return err;
2382 }
2383
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 37722 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC bpf-next 1/2] bpf: add signature to eBPF instructions
2021-10-12 19:00 ` [RFC bpf-next 1/2] bpf: add signature to eBPF instructions Matteo Croce
` (3 preceding siblings ...)
2021-10-13 14:35 ` kernel test robot
@ 2021-10-24 22:35 ` kernel test robot
4 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2021-10-24 22:35 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 11053 bytes --]
Hi Matteo,
[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on bpf-next/master]
url: https://github.com/0day-ci/linux/commits/Matteo-Croce/bpf-sign-bpf-programs/20211013-030207
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
config: mips-randconfig-s031-20211013 (attached as .config)
compiler: mipsel-linux-gcc (GCC) 11.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-dirty
# https://github.com/0day-ci/linux/commit/45c21d28e868dac39e5267e2e2b6f4e35f86b661
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Matteo-Croce/bpf-sign-bpf-programs/20211013-030207
git checkout 45c21d28e868dac39e5267e2e2b6f4e35f86b661
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=mips SHELL=/bin/bash kernel/bpf/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
command-line: note: in included file:
builtin:1:9: sparse: sparse: preprocessor token __ATOMIC_ACQUIRE redefined
builtin:0:0: sparse: this was the original definition
builtin:1:9: sparse: sparse: preprocessor token __ATOMIC_SEQ_CST redefined
builtin:0:0: sparse: this was the original definition
builtin:1:9: sparse: sparse: preprocessor token __ATOMIC_ACQ_REL redefined
builtin:0:0: sparse: this was the original definition
builtin:1:9: sparse: sparse: preprocessor token __ATOMIC_RELEASE redefined
builtin:0:0: sparse: this was the original definition
kernel/bpf/syscall.c:2288:48: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void const [noderef] __user *from @@ got char * @@
kernel/bpf/syscall.c:2288:48: sparse: expected void const [noderef] __user *from
kernel/bpf/syscall.c:2288:48: sparse: got char *
kernel/bpf/syscall.c: note: in included file (through include/linux/bpf.h):
include/linux/bpfptr.h:52:47: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast from non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast from non-scalar
include/linux/bpfptr.h:81:43: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:81:43: sparse: sparse: cast from non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast from non-scalar
>> kernel/bpf/syscall.c:2288:55: sparse: sparse: non size-preserving integer to pointer cast
include/linux/bpfptr.h:52:47: sparse: sparse: cast to non-scalar
include/linux/bpfptr.h:52:47: sparse: sparse: cast from non-scalar
vim +2288 kernel/bpf/syscall.c
2162
2163 static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr)
2164 {
2165 enum bpf_prog_type type = attr->prog_type;
2166 struct bpf_prog *prog, *dst_prog = NULL;
2167 struct btf *attach_btf = NULL;
2168 int err;
2169 char license[128];
2170 bool is_gpl;
2171
2172 if (CHECK_ATTR(BPF_PROG_LOAD))
2173 return -EINVAL;
2174
2175 if (attr->prog_flags & ~(BPF_F_STRICT_ALIGNMENT |
2176 BPF_F_ANY_ALIGNMENT |
2177 BPF_F_TEST_STATE_FREQ |
2178 BPF_F_SLEEPABLE |
2179 BPF_F_TEST_RND_HI32))
2180 return -EINVAL;
2181
2182 if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) &&
2183 (attr->prog_flags & BPF_F_ANY_ALIGNMENT) &&
2184 !bpf_capable())
2185 return -EPERM;
2186
2187 /* copy eBPF program license from user space */
2188 if (strncpy_from_bpfptr(license,
2189 make_bpfptr(attr->license, uattr.is_kernel),
2190 sizeof(license) - 1) < 0)
2191 return -EFAULT;
2192 license[sizeof(license) - 1] = 0;
2193
2194 /* eBPF programs must be GPL compatible to use GPL-ed functions */
2195 is_gpl = license_is_gpl_compatible(license);
2196
2197 if (attr->insn_cnt == 0 ||
2198 attr->insn_cnt > (bpf_capable() ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS))
2199 return -E2BIG;
2200 if (type != BPF_PROG_TYPE_SOCKET_FILTER &&
2201 type != BPF_PROG_TYPE_CGROUP_SKB &&
2202 !bpf_capable())
2203 return -EPERM;
2204
2205 if (is_net_admin_prog_type(type) && !capable(CAP_NET_ADMIN) && !capable(CAP_SYS_ADMIN))
2206 return -EPERM;
2207 if (is_perfmon_prog_type(type) && !perfmon_capable())
2208 return -EPERM;
2209
2210 /* attach_prog_fd/attach_btf_obj_fd can specify fd of either bpf_prog
2211 * or btf, we need to check which one it is
2212 */
2213 if (attr->attach_prog_fd) {
2214 dst_prog = bpf_prog_get(attr->attach_prog_fd);
2215 if (IS_ERR(dst_prog)) {
2216 dst_prog = NULL;
2217 attach_btf = btf_get_by_fd(attr->attach_btf_obj_fd);
2218 if (IS_ERR(attach_btf))
2219 return -EINVAL;
2220 if (!btf_is_kernel(attach_btf)) {
2221 /* attaching through specifying bpf_prog's BTF
2222 * objects directly might be supported eventually
2223 */
2224 btf_put(attach_btf);
2225 return -ENOTSUPP;
2226 }
2227 }
2228 } else if (attr->attach_btf_id) {
2229 /* fall back to vmlinux BTF, if BTF type ID is specified */
2230 attach_btf = bpf_get_btf_vmlinux();
2231 if (IS_ERR(attach_btf))
2232 return PTR_ERR(attach_btf);
2233 if (!attach_btf)
2234 return -EINVAL;
2235 btf_get(attach_btf);
2236 }
2237
2238 bpf_prog_load_fixup_attach_type(attr);
2239 if (bpf_prog_load_check_attach(type, attr->expected_attach_type,
2240 attach_btf, attr->attach_btf_id,
2241 dst_prog)) {
2242 if (dst_prog)
2243 bpf_prog_put(dst_prog);
2244 if (attach_btf)
2245 btf_put(attach_btf);
2246 return -EINVAL;
2247 }
2248
2249 /* plain bpf_prog allocation */
2250 prog = bpf_prog_alloc(bpf_prog_size(attr->insn_cnt), GFP_USER);
2251 if (!prog) {
2252 if (dst_prog)
2253 bpf_prog_put(dst_prog);
2254 if (attach_btf)
2255 btf_put(attach_btf);
2256 return -ENOMEM;
2257 }
2258
2259 prog->expected_attach_type = attr->expected_attach_type;
2260 prog->aux->attach_btf = attach_btf;
2261 prog->aux->attach_btf_id = attr->attach_btf_id;
2262 prog->aux->dst_prog = dst_prog;
2263 prog->aux->offload_requested = !!attr->prog_ifindex;
2264 prog->aux->sleepable = attr->prog_flags & BPF_F_SLEEPABLE;
2265
2266 err = security_bpf_prog_alloc(prog->aux);
2267 if (err)
2268 goto free_prog;
2269
2270 prog->aux->user = get_current_user();
2271 prog->len = attr->insn_cnt;
2272
2273 err = -EFAULT;
2274 if (copy_from_bpfptr(prog->insns,
2275 make_bpfptr(attr->insns, uattr.is_kernel),
2276 bpf_prog_insn_size(prog)) != 0)
2277 goto free_prog_sec;
2278
2279 if (attr->sig_len) {
2280 char *signature;
2281
2282 signature = kmalloc(attr->sig_len, GFP_USER);
2283 if (!signature) {
2284 err = -ENOMEM;
2285 goto free_prog_sec;
2286 }
2287
> 2288 if (copy_from_user(signature, (char *)attr->signature, attr->sig_len)) {
2289 err = -EFAULT;
2290 kfree(signature);
2291 goto free_prog_sec;
2292 }
2293
2294 err = verify_pkcs7_signature(prog->insns,
2295 prog->len * sizeof(struct bpf_insn),
2296 signature, attr->sig_len,
2297 VERIFY_USE_SECONDARY_KEYRING,
2298 VERIFYING_MODULE_SIGNATURE,
2299 NULL, NULL);
2300 kfree(signature);
2301
2302 if (err) {
2303 printk("verify_pkcs7_signature(): %pe\n", (void*)(uintptr_t)err);
2304 goto free_prog_sec;
2305 }
2306 }
2307
2308 prog->orig_prog = NULL;
2309 prog->jited = 0;
2310
2311 atomic64_set(&prog->aux->refcnt, 1);
2312 prog->gpl_compatible = is_gpl ? 1 : 0;
2313
2314 if (bpf_prog_is_dev_bound(prog->aux)) {
2315 err = bpf_prog_offload_init(prog, attr);
2316 if (err)
2317 goto free_prog_sec;
2318 }
2319
2320 /* find program type: socket_filter vs tracing_filter */
2321 err = find_prog_type(type, prog);
2322 if (err < 0)
2323 goto free_prog_sec;
2324
2325 prog->aux->load_time = ktime_get_boottime_ns();
2326 err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name,
2327 sizeof(attr->prog_name));
2328 if (err < 0)
2329 goto free_prog_sec;
2330
2331 /* run eBPF verifier */
2332 err = bpf_check(&prog, attr, uattr);
2333 if (err < 0)
2334 goto free_used_maps;
2335
2336 prog = bpf_prog_select_runtime(prog, &err);
2337 if (err < 0)
2338 goto free_used_maps;
2339
2340 err = bpf_prog_alloc_id(prog);
2341 if (err)
2342 goto free_used_maps;
2343
2344 /* Upon success of bpf_prog_alloc_id(), the BPF prog is
2345 * effectively publicly exposed. However, retrieving via
2346 * bpf_prog_get_fd_by_id() will take another reference,
2347 * therefore it cannot be gone underneath us.
2348 *
2349 * Only for the time /after/ successful bpf_prog_new_fd()
2350 * and before returning to userspace, we might just hold
2351 * one reference and any parallel close on that fd could
2352 * rip everything out. Hence, below notifications must
2353 * happen before bpf_prog_new_fd().
2354 *
2355 * Also, any failure handling from this point onwards must
2356 * be using bpf_prog_put() given the program is exposed.
2357 */
2358 bpf_prog_kallsyms_add(prog);
2359 perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_LOAD, 0);
2360 bpf_audit_prog(prog, BPF_AUDIT_LOAD);
2361
2362 err = bpf_prog_new_fd(prog);
2363 if (err < 0)
2364 bpf_prog_put(prog);
2365 return err;
2366
2367 free_used_maps:
2368 /* In case we have subprogs, we need to wait for a grace
2369 * period before we can tear down JIT memory since symbols
2370 * are already exposed under kallsyms.
2371 */
2372 __bpf_prog_put_noref(prog, prog->aux->func_cnt);
2373 return err;
2374 free_prog_sec:
2375 free_uid(prog->aux->user);
2376 security_bpf_prog_free(prog->aux);
2377 free_prog:
2378 if (prog->aux->attach_btf)
2379 btf_put(prog->aux->attach_btf);
2380 bpf_prog_free(prog);
2381 return err;
2382 }
2383
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 37722 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC bpf-next 1/2] bpf: add signature to eBPF instructions
2021-10-12 18:58 [RFC bpf-next 1/2] bpf: add signature to eBPF instructions Matteo Croce
@ 2021-10-12 19:02 ` Matteo Croce
0 siblings, 0 replies; 10+ messages in thread
From: Matteo Croce @ 2021-10-12 19:02 UTC (permalink / raw)
To: bpf
Cc: Linux Kernel Mailing List, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Arnaldo Carvalho de Melo, Luca Boccassi,
David S. Miller
On Tue, Oct 12, 2021 at 8:59 PM Matteo Croce <mcroce@linux.microsoft.com> wrote:
>
> From: Matteo Croce <mcroce@microsoft.com>
>
> When loading a BPF program, pass a signature which is used to validate
> the instructions.
> The signature type is the same used to validate the kernel modules.
>
> Signed-off-by: Matteo Croce <mcroce@microsoft.com>
> ---
Slipped out by mistake, duplicate of:
https://lore.kernel.org/bpf/20211012190028.54828-2-mcroce@linux.microsoft.com/T/#u
Sorry,
--
per aspera ad upstream
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC bpf-next 1/2] bpf: add signature to eBPF instructions
@ 2021-10-12 18:58 Matteo Croce
2021-10-12 19:02 ` Matteo Croce
0 siblings, 1 reply; 10+ messages in thread
From: Matteo Croce @ 2021-10-12 18:58 UTC (permalink / raw)
To: bpf
Cc: linux-kernel, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Arnaldo Carvalho de Melo, Luca Boccassi,
David S. Miller
From: Matteo Croce <mcroce@microsoft.com>
When loading a BPF program, pass a signature which is used to validate
the instructions.
The signature type is the same used to validate the kernel modules.
Signed-off-by: Matteo Croce <mcroce@microsoft.com>
---
include/uapi/linux/bpf.h | 2 ++
kernel/bpf/syscall.c | 33 ++++++++++++++++++++++++++++++++-
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index c2b8857b8a1c..b9d259f26e92 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1336,6 +1336,8 @@ union bpf_attr {
};
__u32 :32; /* pad */
__aligned_u64 fd_array; /* array of FDs */
+ __aligned_u64 signature; /* instruction's signature */
+ __u32 sig_len; /* signature size */
};
struct { /* anonymous struct used by BPF_OBJ_* commands */
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 3c349b244a28..5589f655033d 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -31,6 +31,8 @@
#include <linux/bpf-netns.h>
#include <linux/rcupdate_trace.h>
#include <linux/memcontrol.h>
+#include <linux/verification.h>
+#include <linux/module_signature.h>
#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
(map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \
@@ -2156,7 +2158,7 @@ static bool is_perfmon_prog_type(enum bpf_prog_type prog_type)
}
/* last field in 'union bpf_attr' used by this command */
-#define BPF_PROG_LOAD_LAST_FIELD fd_array
+#define BPF_PROG_LOAD_LAST_FIELD sig_len
static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr)
{
@@ -2274,6 +2276,35 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr)
bpf_prog_insn_size(prog)) != 0)
goto free_prog_sec;
+ if (attr->sig_len) {
+ char *signature;
+
+ signature = kmalloc(attr->sig_len, GFP_USER);
+ if (!signature) {
+ err = -ENOMEM;
+ goto free_prog_sec;
+ }
+
+ if (copy_from_user(signature, (char *)attr->signature, attr->sig_len)) {
+ err = -EFAULT;
+ kfree(signature);
+ goto free_prog_sec;
+ }
+
+ err = verify_pkcs7_signature(prog->insns,
+ prog->len * sizeof(struct bpf_insn),
+ signature, attr->sig_len,
+ VERIFY_USE_SECONDARY_KEYRING,
+ VERIFYING_MODULE_SIGNATURE,
+ NULL, NULL);
+ kfree(signature);
+
+ if (err) {
+ printk("verify_pkcs7_signature(): %pe\n", (void*)(uintptr_t)err);
+ goto free_prog_sec;
+ }
+ }
+
prog->orig_prog = NULL;
prog->jited = 0;
--
2.33.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-10-24 22:35 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-12 19:00 [RFC bpf-next 0/2] bpf: sign bpf programs Matteo Croce
2021-10-12 19:00 ` [RFC bpf-next 1/2] bpf: add signature to eBPF instructions Matteo Croce
2021-10-13 2:37 ` kernel test robot
2021-10-13 3:13 ` kernel test robot
2021-10-13 3:36 ` kernel test robot
2021-10-13 14:35 ` kernel test robot
2021-10-24 22:35 ` kernel test robot
2021-10-12 19:00 ` [RFC bpf-next 2/2] bpftool: add signature in skeleton Matteo Croce
-- strict thread matches above, loose matches on Subject: below --
2021-10-12 18:58 [RFC bpf-next 1/2] bpf: add signature to eBPF instructions Matteo Croce
2021-10-12 19:02 ` Matteo Croce
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.