* [PATCH bpf-next 0/2] enforce W^X for trampoline and dispatcher
@ 2022-09-23 21:18 Song Liu
2022-09-23 21:18 ` [PATCH bpf-next 1/2] bpf: use bpf_prog_pack for bpf_dispatcher Song Liu
2022-09-23 21:18 ` [PATCH bpf-next 2/2] bpf: Enforce W^X for bpf trampoline Song Liu
0 siblings, 2 replies; 8+ messages in thread
From: Song Liu @ 2022-09-23 21:18 UTC (permalink / raw)
To: bpf
Cc: ast, daniel, john.fastabend, kpsingh, kernel-team, haoluo,
jlayton, Song Liu
Jeff Layton reported CPA W^X warning linux-next [1]. It turns out to be
W^X issue with bpf trampoline and bpf dispatcher. Fix these by:
1. Use bpf_prog_pack for bpf_dispatcher;
2. Set memory permission properly with bpf trampoline.
[1] https://lore.kernel.org/lkml/c84cc27c1a5031a003039748c3c099732a718aec.camel@kernel.org/
Song Liu (2):
bpf: use bpf_prog_pack for bpf_dispatcher
bpf: Enforce W^X for bpf trampoline
include/linux/bpf.h | 2 +-
include/linux/filter.h | 5 +++++
kernel/bpf/core.c | 9 +++++++--
kernel/bpf/dispatcher.c | 21 ++++++++++++++++++---
kernel/bpf/trampoline.c | 22 +++++-----------------
5 files changed, 36 insertions(+), 23 deletions(-)
--
2.30.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH bpf-next 1/2] bpf: use bpf_prog_pack for bpf_dispatcher
2022-09-23 21:18 [PATCH bpf-next 0/2] enforce W^X for trampoline and dispatcher Song Liu
@ 2022-09-23 21:18 ` Song Liu
2022-09-23 22:00 ` Alexei Starovoitov
2022-09-23 21:18 ` [PATCH bpf-next 2/2] bpf: Enforce W^X for bpf trampoline Song Liu
1 sibling, 1 reply; 8+ messages in thread
From: Song Liu @ 2022-09-23 21:18 UTC (permalink / raw)
To: bpf
Cc: ast, daniel, john.fastabend, kpsingh, kernel-team, haoluo,
jlayton, Song Liu
Allocate bpf_dispatcher with bpf_prog_pack_alloc so that bpf_dispatcher
can share pages with bpf programs.
This also fixes CPA W^X warnning like:
CPA refuse W^X violation: 8000000000000163 -> 0000000000000163 range: ...
Signed-off-by: Song Liu <song@kernel.org>
---
include/linux/bpf.h | 1 +
include/linux/filter.h | 5 +++++
kernel/bpf/core.c | 9 +++++++--
kernel/bpf/dispatcher.c | 21 ++++++++++++++++++---
4 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index edd43edb27d6..a8d0cfe14372 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -946,6 +946,7 @@ struct bpf_dispatcher {
struct bpf_dispatcher_prog progs[BPF_DISPATCHER_MAX];
int num_progs;
void *image;
+ void *rw_image;
u32 image_off;
struct bpf_ksym ksym;
};
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 98e28126c24b..efc42a6e3aed 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -1023,6 +1023,8 @@ extern long bpf_jit_limit_max;
typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);
+void bpf_jit_fill_hole_with_zero(void *area, unsigned int size);
+
struct bpf_binary_header *
bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
unsigned int alignment,
@@ -1035,6 +1037,9 @@ void bpf_jit_free(struct bpf_prog *fp);
struct bpf_binary_header *
bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);
+void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns);
+void bpf_prog_pack_free(struct bpf_binary_header *hdr);
+
static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
{
return list_empty(&fp->aux->ksym.lnode) ||
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index d1be78c28619..711fd293b6de 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -825,6 +825,11 @@ struct bpf_prog_pack {
unsigned long bitmap[];
};
+void bpf_jit_fill_hole_with_zero(void *area, unsigned int size)
+{
+ memset(area, 0, size);
+}
+
#define BPF_PROG_SIZE_TO_NBITS(size) (round_up(size, BPF_PROG_CHUNK_SIZE) / BPF_PROG_CHUNK_SIZE)
static DEFINE_MUTEX(pack_mutex);
@@ -864,7 +869,7 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
return pack;
}
-static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
+void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
{
unsigned int nbits = BPF_PROG_SIZE_TO_NBITS(size);
struct bpf_prog_pack *pack;
@@ -905,7 +910,7 @@ static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insn
return ptr;
}
-static void bpf_prog_pack_free(struct bpf_binary_header *hdr)
+void bpf_prog_pack_free(struct bpf_binary_header *hdr)
{
struct bpf_prog_pack *pack = NULL, *tmp;
unsigned int nbits;
diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
index 2444bd15cc2d..8a10300854b6 100644
--- a/kernel/bpf/dispatcher.c
+++ b/kernel/bpf/dispatcher.c
@@ -104,7 +104,7 @@ static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image)
static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
{
- void *old, *new;
+ void *old, *new, *tmp;
u32 noff;
int err;
@@ -117,8 +117,14 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
}
new = d->num_progs ? d->image + noff : NULL;
+ tmp = d->num_progs ? d->rw_image + noff : NULL;
if (new) {
- if (bpf_dispatcher_prepare(d, new))
+ /* Prepare the dispatcher in d->rw_image. Then use
+ * bpf_arch_text_copy to update d->image, which is RO+X.
+ */
+ if (bpf_dispatcher_prepare(d, tmp))
+ return;
+ if (IS_ERR(bpf_arch_text_copy(new, tmp, PAGE_SIZE / 2)))
return;
}
@@ -140,9 +146,18 @@ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
mutex_lock(&d->mutex);
if (!d->image) {
- d->image = bpf_jit_alloc_exec_page();
+ d->image = bpf_prog_pack_alloc(PAGE_SIZE, bpf_jit_fill_hole_with_zero);
if (!d->image)
goto out;
+ d->rw_image = bpf_jit_alloc_exec(PAGE_SIZE);
+ if (!d->rw_image) {
+ u32 size = PAGE_SIZE;
+
+ bpf_arch_text_copy(d->image, &size, sizeof(size));
+ bpf_prog_pack_free((struct bpf_binary_header *)d->image);
+ d->image = NULL;
+ goto out;
+ }
bpf_image_ksym_add(d->image, &d->ksym);
}
--
2.30.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH bpf-next 2/2] bpf: Enforce W^X for bpf trampoline
2022-09-23 21:18 [PATCH bpf-next 0/2] enforce W^X for trampoline and dispatcher Song Liu
2022-09-23 21:18 ` [PATCH bpf-next 1/2] bpf: use bpf_prog_pack for bpf_dispatcher Song Liu
@ 2022-09-23 21:18 ` Song Liu
1 sibling, 0 replies; 8+ messages in thread
From: Song Liu @ 2022-09-23 21:18 UTC (permalink / raw)
To: bpf
Cc: ast, daniel, john.fastabend, kpsingh, kernel-team, haoluo,
jlayton, Song Liu
Mark the trampoline as RO+X after arch_prepare_bpf_trampoline, so that
the trampoine follows W^X rule strictly. This will turn off warnings like
CPA refuse W^X violation: 8000000000000163 -> 0000000000000163 range: ...
Also remove bpf_jit_alloc_exec_page(), since it is not used any more.
Signed-off-by: Song Liu <song@kernel.org>
---
include/linux/bpf.h | 1 -
kernel/bpf/trampoline.c | 22 +++++-----------------
2 files changed, 5 insertions(+), 18 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index a8d0cfe14372..44a3d6b3c924 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1008,7 +1008,6 @@ int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs);
void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
struct bpf_prog *to);
/* Called only from JIT-enabled code, so there's no need for stubs. */
-void *bpf_jit_alloc_exec_page(void);
void bpf_image_ksym_add(void *data, struct bpf_ksym *ksym);
void bpf_image_ksym_del(struct bpf_ksym *ksym);
void bpf_ksym_add(struct bpf_ksym *ksym);
diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
index 41b67eb83ab3..6f7b939321d6 100644
--- a/kernel/bpf/trampoline.c
+++ b/kernel/bpf/trampoline.c
@@ -116,22 +116,6 @@ bool bpf_prog_has_trampoline(const struct bpf_prog *prog)
(ptype == BPF_PROG_TYPE_LSM && eatype == BPF_LSM_MAC);
}
-void *bpf_jit_alloc_exec_page(void)
-{
- void *image;
-
- image = bpf_jit_alloc_exec(PAGE_SIZE);
- if (!image)
- return NULL;
-
- set_vm_flush_reset_perms(image);
- /* Keep image as writeable. The alternative is to keep flipping ro/rw
- * every time new program is attached or detached.
- */
- set_memory_x((long)image, 1);
- return image;
-}
-
void bpf_image_ksym_add(void *data, struct bpf_ksym *ksym)
{
ksym->start = (unsigned long) data;
@@ -404,9 +388,10 @@ static struct bpf_tramp_image *bpf_tramp_image_alloc(u64 key, u32 idx)
goto out_free_im;
err = -ENOMEM;
- im->image = image = bpf_jit_alloc_exec_page();
+ im->image = image = bpf_jit_alloc_exec(PAGE_SIZE);
if (!image)
goto out_uncharge;
+ set_vm_flush_reset_perms(image);
err = percpu_ref_init(&im->pcref, __bpf_tramp_image_release, 0, GFP_KERNEL);
if (err)
@@ -483,6 +468,9 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
if (err < 0)
goto out;
+ set_memory_ro((long)im->image, 1);
+ set_memory_x((long)im->image, 1);
+
WARN_ON(tr->cur_image && tr->selector == 0);
WARN_ON(!tr->cur_image && tr->selector);
if (tr->cur_image)
--
2.30.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: use bpf_prog_pack for bpf_dispatcher
2022-09-23 21:18 ` [PATCH bpf-next 1/2] bpf: use bpf_prog_pack for bpf_dispatcher Song Liu
@ 2022-09-23 22:00 ` Alexei Starovoitov
2022-09-23 23:18 ` Song Liu
0 siblings, 1 reply; 8+ messages in thread
From: Alexei Starovoitov @ 2022-09-23 22:00 UTC (permalink / raw)
To: Song Liu
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, John Fastabend,
KP Singh, Kernel Team, Hao Luo, jlayton
On Fri, Sep 23, 2022 at 2:18 PM Song Liu <song@kernel.org> wrote:
>
> Allocate bpf_dispatcher with bpf_prog_pack_alloc so that bpf_dispatcher
> can share pages with bpf programs.
>
> This also fixes CPA W^X warnning like:
>
> CPA refuse W^X violation: 8000000000000163 -> 0000000000000163 range: ...
>
> Signed-off-by: Song Liu <song@kernel.org>
> ---
> include/linux/bpf.h | 1 +
> include/linux/filter.h | 5 +++++
> kernel/bpf/core.c | 9 +++++++--
> kernel/bpf/dispatcher.c | 21 ++++++++++++++++++---
> 4 files changed, 31 insertions(+), 5 deletions(-)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index edd43edb27d6..a8d0cfe14372 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -946,6 +946,7 @@ struct bpf_dispatcher {
> struct bpf_dispatcher_prog progs[BPF_DISPATCHER_MAX];
> int num_progs;
> void *image;
> + void *rw_image;
> u32 image_off;
> struct bpf_ksym ksym;
> };
> diff --git a/include/linux/filter.h b/include/linux/filter.h
> index 98e28126c24b..efc42a6e3aed 100644
> --- a/include/linux/filter.h
> +++ b/include/linux/filter.h
> @@ -1023,6 +1023,8 @@ extern long bpf_jit_limit_max;
>
> typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);
>
> +void bpf_jit_fill_hole_with_zero(void *area, unsigned int size);
> +
> struct bpf_binary_header *
> bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
> unsigned int alignment,
> @@ -1035,6 +1037,9 @@ void bpf_jit_free(struct bpf_prog *fp);
> struct bpf_binary_header *
> bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);
>
> +void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns);
> +void bpf_prog_pack_free(struct bpf_binary_header *hdr);
> +
> static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
> {
> return list_empty(&fp->aux->ksym.lnode) ||
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index d1be78c28619..711fd293b6de 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -825,6 +825,11 @@ struct bpf_prog_pack {
> unsigned long bitmap[];
> };
>
> +void bpf_jit_fill_hole_with_zero(void *area, unsigned int size)
> +{
> + memset(area, 0, size);
> +}
> +
> #define BPF_PROG_SIZE_TO_NBITS(size) (round_up(size, BPF_PROG_CHUNK_SIZE) / BPF_PROG_CHUNK_SIZE)
>
> static DEFINE_MUTEX(pack_mutex);
> @@ -864,7 +869,7 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
> return pack;
> }
>
> -static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
> +void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
> {
> unsigned int nbits = BPF_PROG_SIZE_TO_NBITS(size);
> struct bpf_prog_pack *pack;
> @@ -905,7 +910,7 @@ static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insn
> return ptr;
> }
>
> -static void bpf_prog_pack_free(struct bpf_binary_header *hdr)
> +void bpf_prog_pack_free(struct bpf_binary_header *hdr)
> {
> struct bpf_prog_pack *pack = NULL, *tmp;
> unsigned int nbits;
> diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
> index 2444bd15cc2d..8a10300854b6 100644
> --- a/kernel/bpf/dispatcher.c
> +++ b/kernel/bpf/dispatcher.c
> @@ -104,7 +104,7 @@ static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image)
>
> static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
> {
> - void *old, *new;
> + void *old, *new, *tmp;
> u32 noff;
> int err;
>
> @@ -117,8 +117,14 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
> }
>
> new = d->num_progs ? d->image + noff : NULL;
> + tmp = d->num_progs ? d->rw_image + noff : NULL;
> if (new) {
> - if (bpf_dispatcher_prepare(d, new))
> + /* Prepare the dispatcher in d->rw_image. Then use
> + * bpf_arch_text_copy to update d->image, which is RO+X.
> + */
> + if (bpf_dispatcher_prepare(d, tmp))
> + return;
> + if (IS_ERR(bpf_arch_text_copy(new, tmp, PAGE_SIZE / 2)))
I don't think we can create a dispatcher with one ip
and then copy over into a different location.
See emit_bpf_dispatcher() -> emit_cond_near_jump()
It's a relative offset jump.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: use bpf_prog_pack for bpf_dispatcher
2022-09-23 22:00 ` Alexei Starovoitov
@ 2022-09-23 23:18 ` Song Liu
2022-09-23 23:23 ` Alexei Starovoitov
0 siblings, 1 reply; 8+ messages in thread
From: Song Liu @ 2022-09-23 23:18 UTC (permalink / raw)
To: Alexei Starovoitov, Björn Töpel
Cc: Song Liu, bpf, Alexei Starovoitov, Daniel Borkmann,
John Fastabend, KP Singh, Kernel Team, Hao Luo,
jlayton@kernel.org
+ Björn Töpel
> On Sep 23, 2022, at 3:00 PM, Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
>
> On Fri, Sep 23, 2022 at 2:18 PM Song Liu <song@kernel.org> wrote:
>>
>> Allocate bpf_dispatcher with bpf_prog_pack_alloc so that bpf_dispatcher
>> can share pages with bpf programs.
>>
>> This also fixes CPA W^X warnning like:
>>
>> CPA refuse W^X violation: 8000000000000163 -> 0000000000000163 range: ...
>>
>> Signed-off-by: Song Liu <song@kernel.org>
>> ---
>> include/linux/bpf.h | 1 +
>> include/linux/filter.h | 5 +++++
>> kernel/bpf/core.c | 9 +++++++--
>> kernel/bpf/dispatcher.c | 21 ++++++++++++++++++---
>> 4 files changed, 31 insertions(+), 5 deletions(-)
>>
>> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
>> index edd43edb27d6..a8d0cfe14372 100644
>> --- a/include/linux/bpf.h
>> +++ b/include/linux/bpf.h
>> @@ -946,6 +946,7 @@ struct bpf_dispatcher {
>> struct bpf_dispatcher_prog progs[BPF_DISPATCHER_MAX];
>> int num_progs;
>> void *image;
>> + void *rw_image;
>> u32 image_off;
>> struct bpf_ksym ksym;
>> };
>> diff --git a/include/linux/filter.h b/include/linux/filter.h
>> index 98e28126c24b..efc42a6e3aed 100644
>> --- a/include/linux/filter.h
>> +++ b/include/linux/filter.h
>> @@ -1023,6 +1023,8 @@ extern long bpf_jit_limit_max;
>>
>> typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);
>>
>> +void bpf_jit_fill_hole_with_zero(void *area, unsigned int size);
>> +
>> struct bpf_binary_header *
>> bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
>> unsigned int alignment,
>> @@ -1035,6 +1037,9 @@ void bpf_jit_free(struct bpf_prog *fp);
>> struct bpf_binary_header *
>> bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);
>>
>> +void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns);
>> +void bpf_prog_pack_free(struct bpf_binary_header *hdr);
>> +
>> static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
>> {
>> return list_empty(&fp->aux->ksym.lnode) ||
>> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
>> index d1be78c28619..711fd293b6de 100644
>> --- a/kernel/bpf/core.c
>> +++ b/kernel/bpf/core.c
>> @@ -825,6 +825,11 @@ struct bpf_prog_pack {
>> unsigned long bitmap[];
>> };
>>
>> +void bpf_jit_fill_hole_with_zero(void *area, unsigned int size)
>> +{
>> + memset(area, 0, size);
>> +}
>> +
>> #define BPF_PROG_SIZE_TO_NBITS(size) (round_up(size, BPF_PROG_CHUNK_SIZE) / BPF_PROG_CHUNK_SIZE)
>>
>> static DEFINE_MUTEX(pack_mutex);
>> @@ -864,7 +869,7 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
>> return pack;
>> }
>>
>> -static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
>> +void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
>> {
>> unsigned int nbits = BPF_PROG_SIZE_TO_NBITS(size);
>> struct bpf_prog_pack *pack;
>> @@ -905,7 +910,7 @@ static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insn
>> return ptr;
>> }
>>
>> -static void bpf_prog_pack_free(struct bpf_binary_header *hdr)
>> +void bpf_prog_pack_free(struct bpf_binary_header *hdr)
>> {
>> struct bpf_prog_pack *pack = NULL, *tmp;
>> unsigned int nbits;
>> diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
>> index 2444bd15cc2d..8a10300854b6 100644
>> --- a/kernel/bpf/dispatcher.c
>> +++ b/kernel/bpf/dispatcher.c
>> @@ -104,7 +104,7 @@ static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image)
>>
>> static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
>> {
>> - void *old, *new;
>> + void *old, *new, *tmp;
>> u32 noff;
>> int err;
>>
>> @@ -117,8 +117,14 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
>> }
>>
>> new = d->num_progs ? d->image + noff : NULL;
>> + tmp = d->num_progs ? d->rw_image + noff : NULL;
>> if (new) {
>> - if (bpf_dispatcher_prepare(d, new))
>> + /* Prepare the dispatcher in d->rw_image. Then use
>> + * bpf_arch_text_copy to update d->image, which is RO+X.
>> + */
>> + if (bpf_dispatcher_prepare(d, tmp))
>> + return;
>> + if (IS_ERR(bpf_arch_text_copy(new, tmp, PAGE_SIZE / 2)))
>
> I don't think we can create a dispatcher with one ip
> and then copy over into a different location.
> See emit_bpf_dispatcher() -> emit_cond_near_jump()
> It's a relative offset jump.
Hmm... Yeah, this makes sense. But somehow vmtest doesn't
show any issue with this. Is there a better way to test this?
Thanks,
Song
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: use bpf_prog_pack for bpf_dispatcher
2022-09-23 23:18 ` Song Liu
@ 2022-09-23 23:23 ` Alexei Starovoitov
2022-09-24 0:51 ` Song Liu
0 siblings, 1 reply; 8+ messages in thread
From: Alexei Starovoitov @ 2022-09-23 23:23 UTC (permalink / raw)
To: Song Liu
Cc: Björn Töpel, Song Liu, bpf, Alexei Starovoitov,
Daniel Borkmann, John Fastabend, KP Singh, Kernel Team, Hao Luo,
jlayton@kernel.org
On Fri, Sep 23, 2022 at 4:18 PM Song Liu <songliubraving@fb.com> wrote:
>
> + Björn Töpel
>
> > On Sep 23, 2022, at 3:00 PM, Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> >
> > On Fri, Sep 23, 2022 at 2:18 PM Song Liu <song@kernel.org> wrote:
> >>
> >> Allocate bpf_dispatcher with bpf_prog_pack_alloc so that bpf_dispatcher
> >> can share pages with bpf programs.
> >>
> >> This also fixes CPA W^X warnning like:
> >>
> >> CPA refuse W^X violation: 8000000000000163 -> 0000000000000163 range: ...
> >>
> >> Signed-off-by: Song Liu <song@kernel.org>
> >> ---
> >> include/linux/bpf.h | 1 +
> >> include/linux/filter.h | 5 +++++
> >> kernel/bpf/core.c | 9 +++++++--
> >> kernel/bpf/dispatcher.c | 21 ++++++++++++++++++---
> >> 4 files changed, 31 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> >> index edd43edb27d6..a8d0cfe14372 100644
> >> --- a/include/linux/bpf.h
> >> +++ b/include/linux/bpf.h
> >> @@ -946,6 +946,7 @@ struct bpf_dispatcher {
> >> struct bpf_dispatcher_prog progs[BPF_DISPATCHER_MAX];
> >> int num_progs;
> >> void *image;
> >> + void *rw_image;
> >> u32 image_off;
> >> struct bpf_ksym ksym;
> >> };
> >> diff --git a/include/linux/filter.h b/include/linux/filter.h
> >> index 98e28126c24b..efc42a6e3aed 100644
> >> --- a/include/linux/filter.h
> >> +++ b/include/linux/filter.h
> >> @@ -1023,6 +1023,8 @@ extern long bpf_jit_limit_max;
> >>
> >> typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);
> >>
> >> +void bpf_jit_fill_hole_with_zero(void *area, unsigned int size);
> >> +
> >> struct bpf_binary_header *
> >> bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
> >> unsigned int alignment,
> >> @@ -1035,6 +1037,9 @@ void bpf_jit_free(struct bpf_prog *fp);
> >> struct bpf_binary_header *
> >> bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);
> >>
> >> +void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns);
> >> +void bpf_prog_pack_free(struct bpf_binary_header *hdr);
> >> +
> >> static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
> >> {
> >> return list_empty(&fp->aux->ksym.lnode) ||
> >> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> >> index d1be78c28619..711fd293b6de 100644
> >> --- a/kernel/bpf/core.c
> >> +++ b/kernel/bpf/core.c
> >> @@ -825,6 +825,11 @@ struct bpf_prog_pack {
> >> unsigned long bitmap[];
> >> };
> >>
> >> +void bpf_jit_fill_hole_with_zero(void *area, unsigned int size)
> >> +{
> >> + memset(area, 0, size);
> >> +}
> >> +
> >> #define BPF_PROG_SIZE_TO_NBITS(size) (round_up(size, BPF_PROG_CHUNK_SIZE) / BPF_PROG_CHUNK_SIZE)
> >>
> >> static DEFINE_MUTEX(pack_mutex);
> >> @@ -864,7 +869,7 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
> >> return pack;
> >> }
> >>
> >> -static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
> >> +void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
> >> {
> >> unsigned int nbits = BPF_PROG_SIZE_TO_NBITS(size);
> >> struct bpf_prog_pack *pack;
> >> @@ -905,7 +910,7 @@ static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insn
> >> return ptr;
> >> }
> >>
> >> -static void bpf_prog_pack_free(struct bpf_binary_header *hdr)
> >> +void bpf_prog_pack_free(struct bpf_binary_header *hdr)
> >> {
> >> struct bpf_prog_pack *pack = NULL, *tmp;
> >> unsigned int nbits;
> >> diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
> >> index 2444bd15cc2d..8a10300854b6 100644
> >> --- a/kernel/bpf/dispatcher.c
> >> +++ b/kernel/bpf/dispatcher.c
> >> @@ -104,7 +104,7 @@ static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image)
> >>
> >> static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
> >> {
> >> - void *old, *new;
> >> + void *old, *new, *tmp;
> >> u32 noff;
> >> int err;
> >>
> >> @@ -117,8 +117,14 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
> >> }
> >>
> >> new = d->num_progs ? d->image + noff : NULL;
> >> + tmp = d->num_progs ? d->rw_image + noff : NULL;
> >> if (new) {
> >> - if (bpf_dispatcher_prepare(d, new))
> >> + /* Prepare the dispatcher in d->rw_image. Then use
> >> + * bpf_arch_text_copy to update d->image, which is RO+X.
> >> + */
> >> + if (bpf_dispatcher_prepare(d, tmp))
> >> + return;
> >> + if (IS_ERR(bpf_arch_text_copy(new, tmp, PAGE_SIZE / 2)))
> >
> > I don't think we can create a dispatcher with one ip
> > and then copy over into a different location.
> > See emit_bpf_dispatcher() -> emit_cond_near_jump()
> > It's a relative offset jump.
>
> Hmm... Yeah, this makes sense. But somehow vmtest doesn't
> show any issue with this. Is there a better way to test this?
test_xdp*.sh should surely trigger it,
but I'm surprised the regular test_run doesn't trigger it.
We call bpf_prog_run_xdp() there.
We've added
if (repeat > 1)
bpf_prog_change_xdp(NULL, prog);
there to reduce test_progs time. Maybe it reduced test coverage too much.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: use bpf_prog_pack for bpf_dispatcher
2022-09-23 23:23 ` Alexei Starovoitov
@ 2022-09-24 0:51 ` Song Liu
2022-09-24 1:03 ` Alexei Starovoitov
0 siblings, 1 reply; 8+ messages in thread
From: Song Liu @ 2022-09-24 0:51 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Björn Töpel, Song Liu, bpf, Alexei Starovoitov,
Daniel Borkmann, John Fastabend, KP Singh, Kernel Team, Hao Luo,
jlayton@kernel.org
> On Sep 23, 2022, at 4:23 PM, Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
>
> On Fri, Sep 23, 2022 at 4:18 PM Song Liu <songliubraving@fb.com> wrote:
>>
>> + Björn Töpel
>>
>>> On Sep 23, 2022, at 3:00 PM, Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
>>>
>>> On Fri, Sep 23, 2022 at 2:18 PM Song Liu <song@kernel.org> wrote:
>>>>
>>>> Allocate bpf_dispatcher with bpf_prog_pack_alloc so that bpf_dispatcher
>>>> can share pages with bpf programs.
>>>>
>>>> This also fixes CPA W^X warnning like:
>>>>
>>>> CPA refuse W^X violation: 8000000000000163 -> 0000000000000163 range: ...
>>>>
>>>> Signed-off-by: Song Liu <song@kernel.org>
>>>> ---
>>>> include/linux/bpf.h | 1 +
>>>> include/linux/filter.h | 5 +++++
>>>> kernel/bpf/core.c | 9 +++++++--
>>>> kernel/bpf/dispatcher.c | 21 ++++++++++++++++++---
>>>> 4 files changed, 31 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
>>>> index edd43edb27d6..a8d0cfe14372 100644
>>>> --- a/include/linux/bpf.h
>>>> +++ b/include/linux/bpf.h
>>>> @@ -946,6 +946,7 @@ struct bpf_dispatcher {
>>>> struct bpf_dispatcher_prog progs[BPF_DISPATCHER_MAX];
>>>> int num_progs;
>>>> void *image;
>>>> + void *rw_image;
>>>> u32 image_off;
>>>> struct bpf_ksym ksym;
>>>> };
>>>> diff --git a/include/linux/filter.h b/include/linux/filter.h
>>>> index 98e28126c24b..efc42a6e3aed 100644
>>>> --- a/include/linux/filter.h
>>>> +++ b/include/linux/filter.h
>>>> @@ -1023,6 +1023,8 @@ extern long bpf_jit_limit_max;
>>>>
>>>> typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);
>>>>
>>>> +void bpf_jit_fill_hole_with_zero(void *area, unsigned int size);
>>>> +
>>>> struct bpf_binary_header *
>>>> bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
>>>> unsigned int alignment,
>>>> @@ -1035,6 +1037,9 @@ void bpf_jit_free(struct bpf_prog *fp);
>>>> struct bpf_binary_header *
>>>> bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);
>>>>
>>>> +void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns);
>>>> +void bpf_prog_pack_free(struct bpf_binary_header *hdr);
>>>> +
>>>> static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
>>>> {
>>>> return list_empty(&fp->aux->ksym.lnode) ||
>>>> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
>>>> index d1be78c28619..711fd293b6de 100644
>>>> --- a/kernel/bpf/core.c
>>>> +++ b/kernel/bpf/core.c
>>>> @@ -825,6 +825,11 @@ struct bpf_prog_pack {
>>>> unsigned long bitmap[];
>>>> };
>>>>
>>>> +void bpf_jit_fill_hole_with_zero(void *area, unsigned int size)
>>>> +{
>>>> + memset(area, 0, size);
>>>> +}
>>>> +
>>>> #define BPF_PROG_SIZE_TO_NBITS(size) (round_up(size, BPF_PROG_CHUNK_SIZE) / BPF_PROG_CHUNK_SIZE)
>>>>
>>>> static DEFINE_MUTEX(pack_mutex);
>>>> @@ -864,7 +869,7 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
>>>> return pack;
>>>> }
>>>>
>>>> -static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
>>>> +void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
>>>> {
>>>> unsigned int nbits = BPF_PROG_SIZE_TO_NBITS(size);
>>>> struct bpf_prog_pack *pack;
>>>> @@ -905,7 +910,7 @@ static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insn
>>>> return ptr;
>>>> }
>>>>
>>>> -static void bpf_prog_pack_free(struct bpf_binary_header *hdr)
>>>> +void bpf_prog_pack_free(struct bpf_binary_header *hdr)
>>>> {
>>>> struct bpf_prog_pack *pack = NULL, *tmp;
>>>> unsigned int nbits;
>>>> diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
>>>> index 2444bd15cc2d..8a10300854b6 100644
>>>> --- a/kernel/bpf/dispatcher.c
>>>> +++ b/kernel/bpf/dispatcher.c
>>>> @@ -104,7 +104,7 @@ static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image)
>>>>
>>>> static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
>>>> {
>>>> - void *old, *new;
>>>> + void *old, *new, *tmp;
>>>> u32 noff;
>>>> int err;
>>>>
>>>> @@ -117,8 +117,14 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
>>>> }
>>>>
>>>> new = d->num_progs ? d->image + noff : NULL;
>>>> + tmp = d->num_progs ? d->rw_image + noff : NULL;
>>>> if (new) {
>>>> - if (bpf_dispatcher_prepare(d, new))
>>>> + /* Prepare the dispatcher in d->rw_image. Then use
>>>> + * bpf_arch_text_copy to update d->image, which is RO+X.
>>>> + */
>>>> + if (bpf_dispatcher_prepare(d, tmp))
>>>> + return;
>>>> + if (IS_ERR(bpf_arch_text_copy(new, tmp, PAGE_SIZE / 2)))
>>>
>>> I don't think we can create a dispatcher with one ip
>>> and then copy over into a different location.
>>> See emit_bpf_dispatcher() -> emit_cond_near_jump()
>>> It's a relative offset jump.
>>
>> Hmm... Yeah, this makes sense. But somehow vmtest doesn't
>> show any issue with this. Is there a better way to test this?
>
> test_xdp*.sh should surely trigger it,
text_xdp*.sh seem to give same result w/ and w/o the set (on top
of bpf-next). For example, ./test_xdp_redirect.sh works just fine.
(And I think it shouldn't.)
> but I'm surprised the regular test_run doesn't trigger it.
> We call bpf_prog_run_xdp() there.
> We've added
> if (repeat > 1)
> bpf_prog_change_xdp(NULL, prog);
I removed this from test_run.c, but that didn't change vmtest.
Song
>
> there to reduce test_progs time. Maybe it reduced test coverage too much.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: use bpf_prog_pack for bpf_dispatcher
2022-09-24 0:51 ` Song Liu
@ 2022-09-24 1:03 ` Alexei Starovoitov
0 siblings, 0 replies; 8+ messages in thread
From: Alexei Starovoitov @ 2022-09-24 1:03 UTC (permalink / raw)
To: Song Liu
Cc: Björn Töpel, Song Liu, bpf, Alexei Starovoitov,
Daniel Borkmann, John Fastabend, KP Singh, Kernel Team, Hao Luo,
jlayton@kernel.org
On Fri, Sep 23, 2022 at 5:51 PM Song Liu <songliubraving@fb.com> wrote:
>
>
>
> > On Sep 23, 2022, at 4:23 PM, Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> >
> > On Fri, Sep 23, 2022 at 4:18 PM Song Liu <songliubraving@fb.com> wrote:
> >>
> >> + Björn Töpel
> >>
> >>> On Sep 23, 2022, at 3:00 PM, Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> >>>
> >>> On Fri, Sep 23, 2022 at 2:18 PM Song Liu <song@kernel.org> wrote:
> >>>>
> >>>> Allocate bpf_dispatcher with bpf_prog_pack_alloc so that bpf_dispatcher
> >>>> can share pages with bpf programs.
> >>>>
> >>>> This also fixes CPA W^X warnning like:
> >>>>
> >>>> CPA refuse W^X violation: 8000000000000163 -> 0000000000000163 range: ...
> >>>>
> >>>> Signed-off-by: Song Liu <song@kernel.org>
> >>>> ---
> >>>> include/linux/bpf.h | 1 +
> >>>> include/linux/filter.h | 5 +++++
> >>>> kernel/bpf/core.c | 9 +++++++--
> >>>> kernel/bpf/dispatcher.c | 21 ++++++++++++++++++---
> >>>> 4 files changed, 31 insertions(+), 5 deletions(-)
> >>>>
> >>>> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> >>>> index edd43edb27d6..a8d0cfe14372 100644
> >>>> --- a/include/linux/bpf.h
> >>>> +++ b/include/linux/bpf.h
> >>>> @@ -946,6 +946,7 @@ struct bpf_dispatcher {
> >>>> struct bpf_dispatcher_prog progs[BPF_DISPATCHER_MAX];
> >>>> int num_progs;
> >>>> void *image;
> >>>> + void *rw_image;
> >>>> u32 image_off;
> >>>> struct bpf_ksym ksym;
> >>>> };
> >>>> diff --git a/include/linux/filter.h b/include/linux/filter.h
> >>>> index 98e28126c24b..efc42a6e3aed 100644
> >>>> --- a/include/linux/filter.h
> >>>> +++ b/include/linux/filter.h
> >>>> @@ -1023,6 +1023,8 @@ extern long bpf_jit_limit_max;
> >>>>
> >>>> typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);
> >>>>
> >>>> +void bpf_jit_fill_hole_with_zero(void *area, unsigned int size);
> >>>> +
> >>>> struct bpf_binary_header *
> >>>> bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
> >>>> unsigned int alignment,
> >>>> @@ -1035,6 +1037,9 @@ void bpf_jit_free(struct bpf_prog *fp);
> >>>> struct bpf_binary_header *
> >>>> bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);
> >>>>
> >>>> +void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns);
> >>>> +void bpf_prog_pack_free(struct bpf_binary_header *hdr);
> >>>> +
> >>>> static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
> >>>> {
> >>>> return list_empty(&fp->aux->ksym.lnode) ||
> >>>> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> >>>> index d1be78c28619..711fd293b6de 100644
> >>>> --- a/kernel/bpf/core.c
> >>>> +++ b/kernel/bpf/core.c
> >>>> @@ -825,6 +825,11 @@ struct bpf_prog_pack {
> >>>> unsigned long bitmap[];
> >>>> };
> >>>>
> >>>> +void bpf_jit_fill_hole_with_zero(void *area, unsigned int size)
> >>>> +{
> >>>> + memset(area, 0, size);
> >>>> +}
> >>>> +
> >>>> #define BPF_PROG_SIZE_TO_NBITS(size) (round_up(size, BPF_PROG_CHUNK_SIZE) / BPF_PROG_CHUNK_SIZE)
> >>>>
> >>>> static DEFINE_MUTEX(pack_mutex);
> >>>> @@ -864,7 +869,7 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
> >>>> return pack;
> >>>> }
> >>>>
> >>>> -static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
> >>>> +void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
> >>>> {
> >>>> unsigned int nbits = BPF_PROG_SIZE_TO_NBITS(size);
> >>>> struct bpf_prog_pack *pack;
> >>>> @@ -905,7 +910,7 @@ static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insn
> >>>> return ptr;
> >>>> }
> >>>>
> >>>> -static void bpf_prog_pack_free(struct bpf_binary_header *hdr)
> >>>> +void bpf_prog_pack_free(struct bpf_binary_header *hdr)
> >>>> {
> >>>> struct bpf_prog_pack *pack = NULL, *tmp;
> >>>> unsigned int nbits;
> >>>> diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
> >>>> index 2444bd15cc2d..8a10300854b6 100644
> >>>> --- a/kernel/bpf/dispatcher.c
> >>>> +++ b/kernel/bpf/dispatcher.c
> >>>> @@ -104,7 +104,7 @@ static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image)
> >>>>
> >>>> static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
> >>>> {
> >>>> - void *old, *new;
> >>>> + void *old, *new, *tmp;
> >>>> u32 noff;
> >>>> int err;
> >>>>
> >>>> @@ -117,8 +117,14 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
> >>>> }
> >>>>
> >>>> new = d->num_progs ? d->image + noff : NULL;
> >>>> + tmp = d->num_progs ? d->rw_image + noff : NULL;
> >>>> if (new) {
> >>>> - if (bpf_dispatcher_prepare(d, new))
> >>>> + /* Prepare the dispatcher in d->rw_image. Then use
> >>>> + * bpf_arch_text_copy to update d->image, which is RO+X.
> >>>> + */
> >>>> + if (bpf_dispatcher_prepare(d, tmp))
> >>>> + return;
> >>>> + if (IS_ERR(bpf_arch_text_copy(new, tmp, PAGE_SIZE / 2)))
> >>>
> >>> I don't think we can create a dispatcher with one ip
> >>> and then copy over into a different location.
> >>> See emit_bpf_dispatcher() -> emit_cond_near_jump()
> >>> It's a relative offset jump.
> >>
> >> Hmm... Yeah, this makes sense. But somehow vmtest doesn't
> >> show any issue with this. Is there a better way to test this?
> >
> > test_xdp*.sh should surely trigger it,
>
> text_xdp*.sh seem to give same result w/ and w/o the set (on top
> of bpf-next). For example, ./test_xdp_redirect.sh works just fine.
> (And I think it shouldn't.)
>
>
> > but I'm surprised the regular test_run doesn't trigger it.
> > We call bpf_prog_run_xdp() there.
> > We've added
> > if (repeat > 1)
> > bpf_prog_change_xdp(NULL, prog);
>
> I removed this from test_run.c, but that didn't change vmtest.
Something is broken. That relative jump isn't being triggered.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2022-09-24 1:03 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-23 21:18 [PATCH bpf-next 0/2] enforce W^X for trampoline and dispatcher Song Liu
2022-09-23 21:18 ` [PATCH bpf-next 1/2] bpf: use bpf_prog_pack for bpf_dispatcher Song Liu
2022-09-23 22:00 ` Alexei Starovoitov
2022-09-23 23:18 ` Song Liu
2022-09-23 23:23 ` Alexei Starovoitov
2022-09-24 0:51 ` Song Liu
2022-09-24 1:03 ` Alexei Starovoitov
2022-09-23 21:18 ` [PATCH bpf-next 2/2] bpf: Enforce W^X for bpf trampoline Song Liu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox