* [PATCH v3 0/2] Handle .data.rel.ro correctly and use it for BPF
@ 2025-02-21 13:57 Ard Biesheuvel
2025-02-21 13:57 ` [PATCH v3 1/2] vmlinux.lds: Ensure that const vars with relocations are mapped R/O Ard Biesheuvel
2025-02-21 13:57 ` [PATCH v3 2/2] objtool: Fix C jump table annotations for Clang Ard Biesheuvel
0 siblings, 2 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2025-02-21 13:57 UTC (permalink / raw)
To: linux-kernel
Cc: x86, Huacai Chen, Ard Biesheuvel, Josh Poimboeuf, Peter Zijlstra,
Tiezhu Yang
From: Ard Biesheuvel <ardb@kernel.org>
LoongArch uses PIE codegen for the entire kernel, which has some
implications for how .rodata is populated and emitted into vmlinux.
Changes since v2:
- Rewrite patch titles and commit logs
Changes since v1: [0]
- Always use .data.rel.ro.c_jump_table for C jump tables
- Add Tiezhu Yang's Tested-by
- Split into two patches and rebase onto Linus's tree
[0] https://lore.kernel.org/all/20250218092538.1903204-2-ardb+git@google.com/T/#u
Cc: Josh Poimboeuf <jpoimboe@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
Ard Biesheuvel (2):
vmlinux.lds: Ensure that const vars with relocations are mapped R/O
objtool: Fix C jump table annotations for Clang
include/asm-generic/vmlinux.lds.h | 2 +-
include/linux/compiler.h | 2 +-
tools/objtool/check.c | 7 ++++---
tools/objtool/include/objtool/special.h | 2 +-
4 files changed, 7 insertions(+), 6 deletions(-)
--
2.48.1.601.g30ceb7b040-goog
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/2] vmlinux.lds: Ensure that const vars with relocations are mapped R/O
2025-02-21 13:57 [PATCH v3 0/2] Handle .data.rel.ro correctly and use it for BPF Ard Biesheuvel
@ 2025-02-21 13:57 ` Ard Biesheuvel
2025-02-28 10:47 ` [tip: objtool/urgent] " tip-bot2 for Ard Biesheuvel
2025-02-21 13:57 ` [PATCH v3 2/2] objtool: Fix C jump table annotations for Clang Ard Biesheuvel
1 sibling, 1 reply; 5+ messages in thread
From: Ard Biesheuvel @ 2025-02-21 13:57 UTC (permalink / raw)
To: linux-kernel
Cc: x86, Huacai Chen, Ard Biesheuvel, Josh Poimboeuf, Peter Zijlstra,
Tiezhu Yang, stable
From: Ard Biesheuvel <ardb@kernel.org>
In the kernel, there are architectures (x86, arm64) that perform
boot-time relocation (for KASLR) without relying on PIE codegen. In this
case, all const global objects are emitted into .rodata, including const
objects with fields that will be fixed up by the boot-time relocation
code. This implies that .rodata (and .text in some cases) need to be
writable at boot, but they will usually be mapped read-only as soon as
the boot completes.
When using PIE codegen, the compiler will emit const global objects into
.data.rel.ro rather than .rodata if the object contains fields that need
such fixups at boot-time. This permits the linker to annotate such
regions as requiring read-write access only at load time, but not at
execution time (in user space), while keeping .rodata truly const (in
user space, this is important for reducing the CoW footprint of dynamic
executables).
This distinction does not matter for the kernel, but it does imply that
const data will end up in writable memory if the .data.rel.ro sections
are not treated in a special way, as they will end up in the writable
.data segment by default.
So emit .data.rel.ro into the .rodata segment.
Cc: <stable@vger.kernel.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
include/asm-generic/vmlinux.lds.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 02a4adb4a999..0d5b186abee8 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -457,7 +457,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
. = ALIGN((align)); \
.rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
__start_rodata = .; \
- *(.rodata) *(.rodata.*) \
+ *(.rodata) *(.rodata.*) *(.data.rel.ro*) \
SCHED_DATA \
RO_AFTER_INIT_DATA /* Read only after init */ \
. = ALIGN(8); \
--
2.48.1.601.g30ceb7b040-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v3 2/2] objtool: Fix C jump table annotations for Clang
2025-02-21 13:57 [PATCH v3 0/2] Handle .data.rel.ro correctly and use it for BPF Ard Biesheuvel
2025-02-21 13:57 ` [PATCH v3 1/2] vmlinux.lds: Ensure that const vars with relocations are mapped R/O Ard Biesheuvel
@ 2025-02-21 13:57 ` Ard Biesheuvel
2025-02-28 10:47 ` [tip: objtool/urgent] " tip-bot2 for Ard Biesheuvel
1 sibling, 1 reply; 5+ messages in thread
From: Ard Biesheuvel @ 2025-02-21 13:57 UTC (permalink / raw)
To: linux-kernel
Cc: x86, Huacai Chen, Ard Biesheuvel, Josh Poimboeuf, Peter Zijlstra,
Tiezhu Yang
From: Ard Biesheuvel <ardb@kernel.org>
A C jump table (such as the one used by the BPF interpreter) is a const
global array of absolute code addresses, and this means that the actual
values in the table may not be known until the kernel is booted (e.g.,
when using KASLR or when the kernel VA space is sized dynamically).
When using PIE codegen, the compiler will default to placing such const
global objects in .data.rel.ro (which is annotated as writable), rather
than .rodata (which is annotated as read-only). As C jump tables are
explicitly emitted into .rodata, this used to result in warnings for
LoongArch builds (which uses PIE codegen for the entire kernel) like
Warning: setting incorrect section attributes for .rodata..c_jump_table
due to the fact that the explicitly specified .rodata section inherited
the read-write annotation that the compiler uses for such objects when
using PIE codegen.
This warning was suppressed by explicitly adding the read-only
annotation to the __attribute__((section(""))) string, by commit
c5b1184decc8 ("compiler.h: specify correct attribute for .rodata..c_jump_table")
Unfortunately, this hack does not work on Clang's integrated assembler,
which happily interprets the appended section type and permission
specifiers as part of the section name, which therefore no longer
matches the hard-coded pattern '.rodata..c_jump_table' that objtool
expects, causing it to emit a warning
kernel/bpf/core.o: warning: objtool: ___bpf_prog_run+0x20: sibling call from callable instruction with modified stack frame
Work around this, by emitting C jump tables into .data.rel.ro instead,
which is treated as .rodata by the linker script for all builds, not
just PIE based ones.
Fixes: c5b1184decc8 ("compiler.h: specify correct attribute for .rodata..c_jump_table")
Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn> # on LoongArch
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
include/linux/compiler.h | 2 +-
tools/objtool/check.c | 7 ++++---
tools/objtool/include/objtool/special.h | 2 +-
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 200fd3c5bc70..155385754824 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -110,7 +110,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
/* Unreachable code */
#ifdef CONFIG_OBJTOOL
/* Annotate a C jump table to allow objtool to follow the code flow */
-#define __annotate_jump_table __section(".rodata..c_jump_table,\"a\",@progbits #")
+#define __annotate_jump_table __section(".data.rel.ro.c_jump_table")
#else /* !CONFIG_OBJTOOL */
#define __annotate_jump_table
#endif /* CONFIG_OBJTOOL */
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index be18a0489303..ce973d9d8e6d 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2472,13 +2472,14 @@ static void mark_rodata(struct objtool_file *file)
*
* - .rodata: can contain GCC switch tables
* - .rodata.<func>: same, if -fdata-sections is being used
- * - .rodata..c_jump_table: contains C annotated jump tables
+ * - .data.rel.ro.c_jump_table: contains C annotated jump tables
*
* .rodata.str1.* sections are ignored; they don't contain jump tables.
*/
for_each_sec(file, sec) {
- if (!strncmp(sec->name, ".rodata", 7) &&
- !strstr(sec->name, ".str1.")) {
+ if ((!strncmp(sec->name, ".rodata", 7) &&
+ !strstr(sec->name, ".str1.")) ||
+ !strncmp(sec->name, ".data.rel.ro", 12)) {
sec->rodata = true;
found = true;
}
diff --git a/tools/objtool/include/objtool/special.h b/tools/objtool/include/objtool/special.h
index e7ee7ffccefd..e049679bb17b 100644
--- a/tools/objtool/include/objtool/special.h
+++ b/tools/objtool/include/objtool/special.h
@@ -10,7 +10,7 @@
#include <objtool/check.h>
#include <objtool/elf.h>
-#define C_JUMP_TABLE_SECTION ".rodata..c_jump_table"
+#define C_JUMP_TABLE_SECTION ".data.rel.ro.c_jump_table"
struct special_alt {
struct list_head list;
--
2.48.1.601.g30ceb7b040-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [tip: objtool/urgent] objtool: Fix C jump table annotations for Clang
2025-02-21 13:57 ` [PATCH v3 2/2] objtool: Fix C jump table annotations for Clang Ard Biesheuvel
@ 2025-02-28 10:47 ` tip-bot2 for Ard Biesheuvel
0 siblings, 0 replies; 5+ messages in thread
From: tip-bot2 for Ard Biesheuvel @ 2025-02-28 10:47 UTC (permalink / raw)
To: linux-tip-commits
Cc: Tiezhu Yang, Ard Biesheuvel, Josh Poimboeuf, x86, linux-kernel
The following commit has been merged into the objtool/urgent branch of tip:
Commit-ID: 73cfc53cc3b6380eccf013049574485f64cb83ca
Gitweb: https://git.kernel.org/tip/73cfc53cc3b6380eccf013049574485f64cb83ca
Author: Ard Biesheuvel <ardb@kernel.org>
AuthorDate: Fri, 21 Feb 2025 14:57:07 +01:00
Committer: Josh Poimboeuf <jpoimboe@kernel.org>
CommitterDate: Tue, 25 Feb 2025 09:46:16 -08:00
objtool: Fix C jump table annotations for Clang
A C jump table (such as the one used by the BPF interpreter) is a const
global array of absolute code addresses, and this means that the actual
values in the table may not be known until the kernel is booted (e.g.,
when using KASLR or when the kernel VA space is sized dynamically).
When using PIE codegen, the compiler will default to placing such const
global objects in .data.rel.ro (which is annotated as writable), rather
than .rodata (which is annotated as read-only). As C jump tables are
explicitly emitted into .rodata, this used to result in warnings for
LoongArch builds (which uses PIE codegen for the entire kernel) like
Warning: setting incorrect section attributes for .rodata..c_jump_table
due to the fact that the explicitly specified .rodata section inherited
the read-write annotation that the compiler uses for such objects when
using PIE codegen.
This warning was suppressed by explicitly adding the read-only
annotation to the __attribute__((section(""))) string, by commit
c5b1184decc8 ("compiler.h: specify correct attribute for .rodata..c_jump_table")
Unfortunately, this hack does not work on Clang's integrated assembler,
which happily interprets the appended section type and permission
specifiers as part of the section name, which therefore no longer
matches the hard-coded pattern '.rodata..c_jump_table' that objtool
expects, causing it to emit a warning
kernel/bpf/core.o: warning: objtool: ___bpf_prog_run+0x20: sibling call from callable instruction with modified stack frame
Work around this, by emitting C jump tables into .data.rel.ro instead,
which is treated as .rodata by the linker script for all builds, not
just PIE based ones.
Fixes: c5b1184decc8 ("compiler.h: specify correct attribute for .rodata..c_jump_table")
Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn> # on LoongArch
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20250221135704.431269-6-ardb+git@google.com
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
include/linux/compiler.h | 2 +-
tools/objtool/check.c | 7 ++++---
tools/objtool/include/objtool/special.h | 2 +-
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index b087de2..0c25f3e 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -110,7 +110,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
/* Unreachable code */
#ifdef CONFIG_OBJTOOL
/* Annotate a C jump table to allow objtool to follow the code flow */
-#define __annotate_jump_table __section(".rodata..c_jump_table,\"a\",@progbits #")
+#define __annotate_jump_table __section(".data.rel.ro.c_jump_table")
#else /* !CONFIG_OBJTOOL */
#define __annotate_jump_table
#endif /* CONFIG_OBJTOOL */
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 497cb8d..1b5a1b3 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2471,13 +2471,14 @@ static void mark_rodata(struct objtool_file *file)
*
* - .rodata: can contain GCC switch tables
* - .rodata.<func>: same, if -fdata-sections is being used
- * - .rodata..c_jump_table: contains C annotated jump tables
+ * - .data.rel.ro.c_jump_table: contains C annotated jump tables
*
* .rodata.str1.* sections are ignored; they don't contain jump tables.
*/
for_each_sec(file, sec) {
- if (!strncmp(sec->name, ".rodata", 7) &&
- !strstr(sec->name, ".str1.")) {
+ if ((!strncmp(sec->name, ".rodata", 7) &&
+ !strstr(sec->name, ".str1.")) ||
+ !strncmp(sec->name, ".data.rel.ro", 12)) {
sec->rodata = true;
found = true;
}
diff --git a/tools/objtool/include/objtool/special.h b/tools/objtool/include/objtool/special.h
index e7ee7ff..e049679 100644
--- a/tools/objtool/include/objtool/special.h
+++ b/tools/objtool/include/objtool/special.h
@@ -10,7 +10,7 @@
#include <objtool/check.h>
#include <objtool/elf.h>
-#define C_JUMP_TABLE_SECTION ".rodata..c_jump_table"
+#define C_JUMP_TABLE_SECTION ".data.rel.ro.c_jump_table"
struct special_alt {
struct list_head list;
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [tip: objtool/urgent] vmlinux.lds: Ensure that const vars with relocations are mapped R/O
2025-02-21 13:57 ` [PATCH v3 1/2] vmlinux.lds: Ensure that const vars with relocations are mapped R/O Ard Biesheuvel
@ 2025-02-28 10:47 ` tip-bot2 for Ard Biesheuvel
0 siblings, 0 replies; 5+ messages in thread
From: tip-bot2 for Ard Biesheuvel @ 2025-02-28 10:47 UTC (permalink / raw)
To: linux-tip-commits
Cc: stable, Ard Biesheuvel, Josh Poimboeuf, x86, linux-kernel
The following commit has been merged into the objtool/urgent branch of tip:
Commit-ID: 68f3ea7ee199ef77551e090dfef5a49046ea8443
Gitweb: https://git.kernel.org/tip/68f3ea7ee199ef77551e090dfef5a49046ea8443
Author: Ard Biesheuvel <ardb@kernel.org>
AuthorDate: Fri, 21 Feb 2025 14:57:06 +01:00
Committer: Josh Poimboeuf <jpoimboe@kernel.org>
CommitterDate: Tue, 25 Feb 2025 09:46:15 -08:00
vmlinux.lds: Ensure that const vars with relocations are mapped R/O
In the kernel, there are architectures (x86, arm64) that perform
boot-time relocation (for KASLR) without relying on PIE codegen. In this
case, all const global objects are emitted into .rodata, including const
objects with fields that will be fixed up by the boot-time relocation
code. This implies that .rodata (and .text in some cases) need to be
writable at boot, but they will usually be mapped read-only as soon as
the boot completes.
When using PIE codegen, the compiler will emit const global objects into
.data.rel.ro rather than .rodata if the object contains fields that need
such fixups at boot-time. This permits the linker to annotate such
regions as requiring read-write access only at load time, but not at
execution time (in user space), while keeping .rodata truly const (in
user space, this is important for reducing the CoW footprint of dynamic
executables).
This distinction does not matter for the kernel, but it does imply that
const data will end up in writable memory if the .data.rel.ro sections
are not treated in a special way, as they will end up in the writable
.data segment by default.
So emit .data.rel.ro into the .rodata segment.
Cc: stable@vger.kernel.org
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20250221135704.431269-5-ardb+git@google.com
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
include/asm-generic/vmlinux.lds.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 5450401..337d333 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -457,7 +457,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
. = ALIGN((align)); \
.rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
__start_rodata = .; \
- *(.rodata) *(.rodata.*) \
+ *(.rodata) *(.rodata.*) *(.data.rel.ro*) \
SCHED_DATA \
RO_AFTER_INIT_DATA /* Read only after init */ \
. = ALIGN(8); \
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-02-28 10:47 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-21 13:57 [PATCH v3 0/2] Handle .data.rel.ro correctly and use it for BPF Ard Biesheuvel
2025-02-21 13:57 ` [PATCH v3 1/2] vmlinux.lds: Ensure that const vars with relocations are mapped R/O Ard Biesheuvel
2025-02-28 10:47 ` [tip: objtool/urgent] " tip-bot2 for Ard Biesheuvel
2025-02-21 13:57 ` [PATCH v3 2/2] objtool: Fix C jump table annotations for Clang Ard Biesheuvel
2025-02-28 10:47 ` [tip: objtool/urgent] " tip-bot2 for Ard Biesheuvel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.