libbpf: Make destructors more robust by handling ERR_PTR(err) cases
authorAndrii Nakryiko <andriin@fb.com>
Wed, 29 Jul 2020 23:21:48 +0000 (16:21 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Thu, 30 Jul 2020 22:53:07 +0000 (00:53 +0200)
Most of libbpf "constructors" on failure return ERR_PTR(err) result encoded as
a pointer. It's a common mistake to eventually pass such malformed pointers
into xxx__destroy()/xxx__free() "destructors". So instead of fixing up
clean up code in selftests and user programs, handle such error pointers in
destructors themselves. This works beautifully for NULL pointers passed to
destructors, so might as well just work for error pointers.

Suggested-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Song Liu <songliubraving@fb.com>
Link: https://lore.kernel.org/bpf/20200729232148.896125-1-andriin@fb.com
tools/lib/bpf/btf.c
tools/lib/bpf/btf_dump.c
tools/lib/bpf/libbpf.c

index c9e760e120dc8032b2ea4c10ee0623a59f0ef0f0..ded5b29965f97879dffe7b1fdd72cbde48836b7a 100644 (file)
@@ -386,7 +386,7 @@ __s32 btf__find_by_name_kind(const struct btf *btf, const char *type_name,
 
 void btf__free(struct btf *btf)
 {
-       if (!btf)
+       if (IS_ERR_OR_NULL(btf))
                return;
 
        if (btf->fd >= 0)
@@ -1025,7 +1025,7 @@ static int btf_ext_parse_hdr(__u8 *data, __u32 data_size)
 
 void btf_ext__free(struct btf_ext *btf_ext)
 {
-       if (!btf_ext)
+       if (IS_ERR_OR_NULL(btf_ext))
                return;
        free(btf_ext->data);
        free(btf_ext);
index e1c344504cae3747f585612de8402b13c3488c16..cf711168d34a2c836634ec94093d0bf06b0d3998 100644 (file)
@@ -183,7 +183,7 @@ void btf_dump__free(struct btf_dump *d)
 {
        int i, cnt;
 
-       if (!d)
+       if (IS_ERR_OR_NULL(d))
                return;
 
        free(d->type_states);
index 54830d603feee28bbdd1a91f83ca90e7cf0d86a1..b9f11f854985b7ce74b783f85283e218c12dac72 100644 (file)
@@ -6504,7 +6504,7 @@ void bpf_object__close(struct bpf_object *obj)
 {
        size_t i;
 
-       if (!obj)
+       if (IS_ERR_OR_NULL(obj))
                return;
 
        if (obj->clear_priv)
@@ -7690,7 +7690,7 @@ int bpf_link__destroy(struct bpf_link *link)
 {
        int err = 0;
 
-       if (!link)
+       if (IS_ERR_OR_NULL(link))
                return 0;
 
        if (!link->disconnected && link->detach)
@@ -8502,7 +8502,7 @@ void perf_buffer__free(struct perf_buffer *pb)
 {
        int i;
 
-       if (!pb)
+       if (IS_ERR_OR_NULL(pb))
                return;
        if (pb->cpu_bufs) {
                for (i = 0; i < pb->cpu_cnt; i++) {
@@ -9379,8 +9379,7 @@ void bpf_object__detach_skeleton(struct bpf_object_skeleton *s)
        for (i = 0; i < s->prog_cnt; i++) {
                struct bpf_link **link = s->progs[i].link;
 
-               if (!IS_ERR_OR_NULL(*link))
-                       bpf_link__destroy(*link);
+               bpf_link__destroy(*link);
                *link = NULL;
        }
 }