Several libbpf API functions such as bpf_object__open_file() and bpf_program__pin() allocate memory based on user-provided paths without first validating input length. This can result in out-of-memory errors or different error codes (ENAMETOOLONG, ENOMEM) being returned. This patch adds missing path length checks to ensure all affected APIs return a consistent error code (ENAMETOOLONG) for invalid path lengths, preventing potential memory allocation failures. Additionally, adds some missing NULL pointer checks to prevent potential segmentation faults. Best regards, Signed-off-by: Masoud Aghasi --- tools/lib/bpf/libbpf.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 7162146280a8..bb3f1dd0663e 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -8536,6 +8536,9 @@ bpf_object__open_file(const char *path, const struct bpf_object_open_opts *opts) if (!path) return libbpf_err_ptr(-EINVAL); + if (strlen(path) >= PATH_MAX) + return libbpf_err_ptr(-ENAMETOOLONG); + return libbpf_ptr(bpf_object_open(path, NULL, 0, NULL, opts)); } @@ -9191,11 +9194,17 @@ int bpf_program__pin(struct bpf_program *prog, const char *path) { int err; + if (!prog || !path) + return libbpf_err(-EINVAL); + if (prog->fd < 0) { pr_warn("prog '%s': can't pin program that wasn't loaded\n", prog->name); return libbpf_err(-EINVAL); } + if (strlen(path) >= PATH_MAX) + return libbpf_err(-ENAMETOOLONG); + err = make_parent_dir(path); if (err) return libbpf_err(err); @@ -9218,11 +9227,17 @@ int bpf_program__unpin(struct bpf_program *prog, const char *path) { int err; + if (!prog || !path) + return libbpf_err(-EINVAL); + if (prog->fd < 0) { pr_warn("prog '%s': can't unpin program that wasn't loaded\n", prog->name); return libbpf_err(-EINVAL); } + if (strlen(path) >= PATH_MAX) + return libbpf_err(-ENAMETOOLONG); + err = check_path(path); if (err) return libbpf_err(err); @@ -9269,6 +9284,9 @@ int bpf_map__pin(struct bpf_map *map, const char *path) return libbpf_err(-EEXIST); } + if (strlen(path) >= PATH_MAX) + return libbpf_err(-ENAMETOOLONG); + map->pin_path = strdup(path); if (!map->pin_path) { err = -errno; @@ -9319,6 +9337,8 @@ int bpf_map__unpin(struct bpf_map *map, const char *path) pr_warn("no path to unpin map '%s' from\n", bpf_map__name(map)); return libbpf_err(-EINVAL); + } else if (strlen(path) >= PATH_MAX) { + return libbpf_err(-ENAMETOOLONG); } err = check_path(path); @@ -9339,7 +9359,13 @@ int bpf_map__set_pin_path(struct bpf_map *map, const char *path) { char *new = NULL; + if (!map) + return libbpf_err(-EINVAL); + if (path) { + if (strlen(path) >= PATH_MAX) + return libbpf_err(-ENAMETOOLONG); + new = strdup(path); if (!new) return libbpf_err(-errno); @@ -11432,6 +11458,12 @@ int bpf_link__pin(struct bpf_link *link, const char *path) { int err; + if (!link || !path) + return libbpf_err(-EINVAL); + + if (strlen(path) >= PATH_MAX) + return libbpf_err(-ENAMETOOLONG); + if (link->pin_path) return libbpf_err(-EBUSY); err = make_parent_dir(path); -- 2.47.3