Commit 9d876e79 authored by Daniel Borkmann's avatar Daniel Borkmann Committed by David S. Miller

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 to 74451e66 ("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: 74451e66 ("bpf: make jited programs visible in traces")
Reported-by: default avatarEric Dumazet <edumazet@google.com>
Reported-by: default avatarWillem de Bruijn <willemb@google.com>
Bisected-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Tested-by: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d2852a22
...@@ -898,7 +898,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment