Skip to content

Commit f08a1c6

Browse files
liu-song-6Alexei Starovoitov
authored andcommitted
bpf: Let bpf_prog_pack_free handle any pointer
Currently, bpf_prog_pack_free only can only free pointer to struct bpf_binary_header, which is not flexible. Add a size argument to bpf_prog_pack_free so that it can handle any pointer. Signed-off-by: Song Liu <[email protected]> Acked-by: Ilya Leoshkevich <[email protected]> Tested-by: Ilya Leoshkevich <[email protected]> # on s390x Reviewed-by: Björn Töpel <[email protected]> Acked-by: Jiri Olsa <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 7065eef commit f08a1c6

File tree

3 files changed

+12
-16
lines changed

3 files changed

+12
-16
lines changed

include/linux/filter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1067,7 +1067,7 @@ struct bpf_binary_header *
10671067
bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);
10681068

10691069
void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns);
1070-
void bpf_prog_pack_free(struct bpf_binary_header *hdr);
1070+
void bpf_prog_pack_free(void *ptr, u32 size);
10711071

10721072
static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
10731073
{

kernel/bpf/core.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -928,20 +928,20 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
928928
return ptr;
929929
}
930930

931-
void bpf_prog_pack_free(struct bpf_binary_header *hdr)
931+
void bpf_prog_pack_free(void *ptr, u32 size)
932932
{
933933
struct bpf_prog_pack *pack = NULL, *tmp;
934934
unsigned int nbits;
935935
unsigned long pos;
936936

937937
mutex_lock(&pack_mutex);
938-
if (hdr->size > BPF_PROG_PACK_SIZE) {
939-
bpf_jit_free_exec(hdr);
938+
if (size > BPF_PROG_PACK_SIZE) {
939+
bpf_jit_free_exec(ptr);
940940
goto out;
941941
}
942942

943943
list_for_each_entry(tmp, &pack_list, list) {
944-
if ((void *)hdr >= tmp->ptr && (tmp->ptr + BPF_PROG_PACK_SIZE) > (void *)hdr) {
944+
if (ptr >= tmp->ptr && (tmp->ptr + BPF_PROG_PACK_SIZE) > ptr) {
945945
pack = tmp;
946946
break;
947947
}
@@ -950,10 +950,10 @@ void bpf_prog_pack_free(struct bpf_binary_header *hdr)
950950
if (WARN_ONCE(!pack, "bpf_prog_pack bug\n"))
951951
goto out;
952952

953-
nbits = BPF_PROG_SIZE_TO_NBITS(hdr->size);
954-
pos = ((unsigned long)hdr - (unsigned long)pack->ptr) >> BPF_PROG_CHUNK_SHIFT;
953+
nbits = BPF_PROG_SIZE_TO_NBITS(size);
954+
pos = ((unsigned long)ptr - (unsigned long)pack->ptr) >> BPF_PROG_CHUNK_SHIFT;
955955

956-
WARN_ONCE(bpf_arch_text_invalidate(hdr, hdr->size),
956+
WARN_ONCE(bpf_arch_text_invalidate(ptr, size),
957957
"bpf_prog_pack bug: missing bpf_arch_text_invalidate?\n");
958958

959959
bitmap_clear(pack->bitmap, pos, nbits);
@@ -1100,8 +1100,7 @@ bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **image_ptr,
11001100

11011101
*rw_header = kvmalloc(size, GFP_KERNEL);
11021102
if (!*rw_header) {
1103-
bpf_arch_text_copy(&ro_header->size, &size, sizeof(size));
1104-
bpf_prog_pack_free(ro_header);
1103+
bpf_prog_pack_free(ro_header, size);
11051104
bpf_jit_uncharge_modmem(size);
11061105
return NULL;
11071106
}
@@ -1132,7 +1131,7 @@ int bpf_jit_binary_pack_finalize(struct bpf_prog *prog,
11321131
kvfree(rw_header);
11331132

11341133
if (IS_ERR(ptr)) {
1135-
bpf_prog_pack_free(ro_header);
1134+
bpf_prog_pack_free(ro_header, ro_header->size);
11361135
return PTR_ERR(ptr);
11371136
}
11381137
return 0;
@@ -1153,7 +1152,7 @@ void bpf_jit_binary_pack_free(struct bpf_binary_header *ro_header,
11531152
{
11541153
u32 size = ro_header->size;
11551154

1156-
bpf_prog_pack_free(ro_header);
1155+
bpf_prog_pack_free(ro_header, size);
11571156
kvfree(rw_header);
11581157
bpf_jit_uncharge_modmem(size);
11591158
}

kernel/bpf/dispatcher.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,7 @@ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
150150
goto out;
151151
d->rw_image = bpf_jit_alloc_exec(PAGE_SIZE);
152152
if (!d->rw_image) {
153-
u32 size = PAGE_SIZE;
154-
155-
bpf_arch_text_copy(d->image, &size, sizeof(size));
156-
bpf_prog_pack_free((struct bpf_binary_header *)d->image);
153+
bpf_prog_pack_free(d->image, PAGE_SIZE);
157154
d->image = NULL;
158155
goto out;
159156
}

0 commit comments

Comments
 (0)