* [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; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ messages in thread
end of thread, other threads:[~2021-10-24 22:35 UTC | newest]
Thread overview: 8+ 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
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.