bpf: fix unlocking of jited image when module ronx not set
Eric and Willem reported that they recently saw random crashes when JIT was in use and bisected this to74451e66d5
("bpf: make jited programs visible in traces"). Issue was that the consolidation part added bpf_jit_binary_unlock_ro() that would unlock previously made read-only memory back to read-write. However, DEBUG_SET_MODULE_RONX cannot be used for this to test for presence of set_memory_*() functions. We need to use ARCH_HAS_SET_MEMORY instead to fix this; also add the corresponding bpf_jit_binary_lock_ro() to filter.h. Fixes:74451e66d5
("bpf: make jited programs visible in traces") Reported-by: Eric Dumazet <edumazet@google.com> Reported-by: Willem de Bruijn <willemb@google.com> Bisected-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Tested-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d2852a2240
commit
9d876e79df
|
@ -898,7 +898,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
|
||||||
|
|
||||||
bpf_flush_icache(header, ctx.image + ctx.idx);
|
bpf_flush_icache(header, ctx.image + ctx.idx);
|
||||||
|
|
||||||
set_memory_ro((unsigned long)header, header->pages);
|
bpf_jit_binary_lock_ro(header);
|
||||||
prog->bpf_func = (void *)ctx.image;
|
prog->bpf_func = (void *)ctx.image;
|
||||||
prog->jited = 1;
|
prog->jited = 1;
|
||||||
|
|
||||||
|
|
|
@ -1327,7 +1327,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
|
||||||
print_fn_code(jit.prg_buf, jit.size_prg);
|
print_fn_code(jit.prg_buf, jit.size_prg);
|
||||||
}
|
}
|
||||||
if (jit.prg_buf) {
|
if (jit.prg_buf) {
|
||||||
set_memory_ro((unsigned long)header, header->pages);
|
bpf_jit_binary_lock_ro(header);
|
||||||
fp->bpf_func = (void *) jit.prg_buf;
|
fp->bpf_func = (void *) jit.prg_buf;
|
||||||
fp->jited = 1;
|
fp->jited = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1165,7 +1165,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
|
||||||
|
|
||||||
if (image) {
|
if (image) {
|
||||||
bpf_flush_icache(header, image + proglen);
|
bpf_flush_icache(header, image + proglen);
|
||||||
set_memory_ro((unsigned long)header, header->pages);
|
bpf_jit_binary_lock_ro(header);
|
||||||
prog->bpf_func = (void *)image;
|
prog->bpf_func = (void *)image;
|
||||||
prog->jited = 1;
|
prog->jited = 1;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -551,7 +551,7 @@ static inline bool bpf_prog_was_classic(const struct bpf_prog *prog)
|
||||||
|
|
||||||
#define bpf_classic_proglen(fprog) (fprog->len * sizeof(fprog->filter[0]))
|
#define bpf_classic_proglen(fprog) (fprog->len * sizeof(fprog->filter[0]))
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_SET_MODULE_RONX
|
#ifdef CONFIG_ARCH_HAS_SET_MEMORY
|
||||||
static inline void bpf_prog_lock_ro(struct bpf_prog *fp)
|
static inline void bpf_prog_lock_ro(struct bpf_prog *fp)
|
||||||
{
|
{
|
||||||
set_memory_ro((unsigned long)fp, fp->pages);
|
set_memory_ro((unsigned long)fp, fp->pages);
|
||||||
|
@ -562,6 +562,11 @@ static inline void bpf_prog_unlock_ro(struct bpf_prog *fp)
|
||||||
set_memory_rw((unsigned long)fp, fp->pages);
|
set_memory_rw((unsigned long)fp, fp->pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr)
|
||||||
|
{
|
||||||
|
set_memory_ro((unsigned long)hdr, hdr->pages);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void bpf_jit_binary_unlock_ro(struct bpf_binary_header *hdr)
|
static inline void bpf_jit_binary_unlock_ro(struct bpf_binary_header *hdr)
|
||||||
{
|
{
|
||||||
set_memory_rw((unsigned long)hdr, hdr->pages);
|
set_memory_rw((unsigned long)hdr, hdr->pages);
|
||||||
|
@ -575,10 +580,14 @@ static inline void bpf_prog_unlock_ro(struct bpf_prog *fp)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static inline void bpf_jit_binary_unlock_ro(struct bpf_binary_header *hdr)
|
static inline void bpf_jit_binary_unlock_ro(struct bpf_binary_header *hdr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DEBUG_SET_MODULE_RONX */
|
#endif /* CONFIG_ARCH_HAS_SET_MEMORY */
|
||||||
|
|
||||||
static inline struct bpf_binary_header *
|
static inline struct bpf_binary_header *
|
||||||
bpf_jit_binary_hdr(const struct bpf_prog *fp)
|
bpf_jit_binary_hdr(const struct bpf_prog *fp)
|
||||||
|
|
Loading…
Reference in New Issue