From 19729e1302017ef33e139903b28f9a778b2a8748 Mon Sep 17 00:00:00 2001 From: Andrea Claudi Date: Thu, 13 Jun 2019 14:37:56 +0200 Subject: [PATCH] bpf: remove strict dependency on af_alg Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361 Upstream Status: iproute2.git commit 6e5094dbb7c06 commit 6e5094dbb7c0682a9ca6eb2a64ec51f0a8a33a22 Author: Daniel Borkmann Date: Wed Jul 18 01:31:20 2018 +0200 bpf: remove strict dependency on af_alg Do not bail out when AF_ALG is not supported by the kernel and only do so when a map is requested in object ns where we're calculating the hash. Otherwise, the loader can operate just fine, therefore lets not fail early when it's not needed. Signed-off-by: Daniel Borkmann Signed-off-by: David Ahern --- lib/bpf.c | 74 +++++++++++++++++++++---------------------------------- 1 file changed, 28 insertions(+), 46 deletions(-) diff --git a/lib/bpf.c b/lib/bpf.c index 9dc37c787d907..ead8b5a7219f0 100644 --- a/lib/bpf.c +++ b/lib/bpf.c @@ -1130,6 +1130,7 @@ struct bpf_elf_ctx { GElf_Ehdr elf_hdr; Elf_Data *sym_tab; Elf_Data *str_tab; + char obj_uid[64]; int obj_fd; int map_fds[ELF_MAX_MAPS]; struct bpf_elf_map maps[ELF_MAX_MAPS]; @@ -1143,6 +1144,7 @@ struct bpf_elf_ctx { enum bpf_prog_type type; __u32 ifindex; bool verbose; + bool noafalg; struct bpf_elf_st stat; struct bpf_hash_entry *ht[256]; char *log; @@ -1258,22 +1260,15 @@ static int bpf_obj_hash(const char *object, uint8_t *out, size_t len) return -EINVAL; cfd = socket(AF_ALG, SOCK_SEQPACKET, 0); - if (cfd < 0) { - fprintf(stderr, "Cannot get AF_ALG socket: %s\n", - strerror(errno)); + if (cfd < 0) return cfd; - } ret = bind(cfd, (struct sockaddr *)&alg, sizeof(alg)); - if (ret < 0) { - fprintf(stderr, "Error binding socket: %s\n", strerror(errno)); + if (ret < 0) goto out_cfd; - } ofd = accept(cfd, NULL, 0); if (ofd < 0) { - fprintf(stderr, "Error accepting socket: %s\n", - strerror(errno)); ret = ofd; goto out_cfd; } @@ -1318,29 +1313,7 @@ out_cfd: return ret; } -static const char *bpf_get_obj_uid(const char *pathname) -{ - static bool bpf_uid_cached; - static char bpf_uid[64]; - uint8_t tmp[20]; - int ret; - - if (bpf_uid_cached) - goto done; - - ret = bpf_obj_hash(pathname, tmp, sizeof(tmp)); - if (ret) { - fprintf(stderr, "Object hashing failed!\n"); - return NULL; - } - - hexstring_n2a(tmp, sizeof(tmp), bpf_uid, sizeof(bpf_uid)); - bpf_uid_cached = true; -done: - return bpf_uid; -} - -static int bpf_init_env(const char *pathname) +static void bpf_init_env(void) { struct rlimit limit = { .rlim_cur = RLIM_INFINITY, @@ -1350,15 +1323,8 @@ static int bpf_init_env(const char *pathname) /* Don't bother in case we fail! */ setrlimit(RLIMIT_MEMLOCK, &limit); - if (!bpf_get_work_dir(BPF_PROG_TYPE_UNSPEC)) { + if (!bpf_get_work_dir(BPF_PROG_TYPE_UNSPEC)) fprintf(stderr, "Continuing without mounted eBPF fs. Too old kernel?\n"); - return 0; - } - - if (!bpf_get_obj_uid(pathname)) - return -1; - - return 0; } static const char *bpf_custom_pinning(const struct bpf_elf_ctx *ctx, @@ -1394,7 +1360,7 @@ static void bpf_make_pathname(char *pathname, size_t len, const char *name, case PIN_OBJECT_NS: snprintf(pathname, len, "%s/%s/%s", bpf_get_work_dir(ctx->type), - bpf_get_obj_uid(NULL), name); + ctx->obj_uid, name); break; case PIN_GLOBAL_NS: snprintf(pathname, len, "%s/%s/%s", @@ -1427,7 +1393,7 @@ static int bpf_make_obj_path(const struct bpf_elf_ctx *ctx) int ret; snprintf(tmp, sizeof(tmp), "%s/%s", bpf_get_work_dir(ctx->type), - bpf_get_obj_uid(NULL)); + ctx->obj_uid); ret = mkdir(tmp, S_IRWXU); if (ret && errno != EEXIST) { @@ -1696,6 +1662,12 @@ static int bpf_maps_attach_all(struct bpf_elf_ctx *ctx) const char *map_name; for (i = 0; i < ctx->map_num; i++) { + if (ctx->maps[i].pinning == PIN_OBJECT_NS && + ctx->noafalg) { + fprintf(stderr, "Missing kernel AF_ALG support for PIN_OBJECT_NS!\n"); + return -ENOTSUP; + } + map_name = bpf_map_fetch_name(ctx, i); if (!map_name) return -EIO; @@ -2451,14 +2423,24 @@ static int bpf_elf_ctx_init(struct bpf_elf_ctx *ctx, const char *pathname, enum bpf_prog_type type, __u32 ifindex, bool verbose) { - int ret = -EINVAL; + uint8_t tmp[20]; + int ret; - if (elf_version(EV_CURRENT) == EV_NONE || - bpf_init_env(pathname)) - return ret; + if (elf_version(EV_CURRENT) == EV_NONE) + return -EINVAL; + + bpf_init_env(); memset(ctx, 0, sizeof(*ctx)); bpf_get_cfg(ctx); + + ret = bpf_obj_hash(pathname, tmp, sizeof(tmp)); + if (ret) + ctx->noafalg = true; + else + hexstring_n2a(tmp, sizeof(tmp), ctx->obj_uid, + sizeof(ctx->obj_uid)); + ctx->verbose = verbose; ctx->type = type; ctx->ifindex = ifindex; -- 2.20.1