[PATCH 2/2] vdso: Reject absolute relocations during build

Thomas Weißschuh posted 2 patches 9 months, 2 weeks ago
There is a newer version of this series
[PATCH 2/2] vdso: Reject absolute relocations during build
Posted by Thomas Weißschuh 9 months, 2 weeks ago
All vDSO code needs to be completely position independent.
Symbol references are marked as hidden so the compiler is forced to emit
PC-relative relocations.
If the compiler does however emit an absolute relocation this will be
resolved by the linker and break at runtime.

Introduce a build-time check for absolute relocations.
The check is done on the object files as the relocations will not exist
anymore in the final DSO. As there is no extension point for the
compilation of each object file perform the validation in vdso_check.

Link: https://lore.kernel.org/lkml/aApGPAoctq_eoE2g@t14ultra/
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
 lib/vdso/Makefile.include | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lib/vdso/Makefile.include b/lib/vdso/Makefile.include
index cedbf15f80874d4bb27c097244bc5b11272f261c..18fcc94e4d6bf7abf374c7a953349e7ad75f8a18 100644
--- a/lib/vdso/Makefile.include
+++ b/lib/vdso/Makefile.include
@@ -12,7 +12,12 @@ c-getrandom-$(CONFIG_VDSO_GETRANDOM) := $(addprefix $(GENERIC_VDSO_DIR), getrand
 #
 # As a workaround for some GNU ld ports which produce unneeded R_*_NONE
 # dynamic relocations, ignore R_*_NONE.
+#
+# Also validate that no absolute relocations are present in the object files themselves.
 quiet_cmd_vdso_check = VDSOCHK $@
       cmd_vdso_check = if $(READELF) -rW $@ | grep -v _NONE | grep -q " R_\w*_"; \
 		       then (echo >&2 "$@: dynamic relocations are not supported"; \
+			     rm -f $@; /bin/false); fi && \
+		       if $(READELF) -rW $(filter %.o, $(real-prereqs)) | grep -q " R_\w*_ABS"; \
+		       then (echo >&2 "$@: absolute relocations are not supported"; \
 			     rm -f $@; /bin/false); fi

-- 
2.49.0

Re: [PATCH 2/2] vdso: Reject absolute relocations during build
Posted by Jan Stancek 9 months, 2 weeks ago
On Tue, Apr 29, 2025 at 2:56 PM Thomas Weißschuh
<thomas.weissschuh@linutronix.de> wrote:
>
> All vDSO code needs to be completely position independent.
> Symbol references are marked as hidden so the compiler is forced to emit
> PC-relative relocations.
> If the compiler does however emit an absolute relocation this will be
> resolved by the linker and break at runtime.
>
> Introduce a build-time check for absolute relocations.
> The check is done on the object files as the relocations will not exist
> anymore in the final DSO. As there is no extension point for the
> compilation of each object file perform the validation in vdso_check.
>
> Link: https://lore.kernel.org/lkml/aApGPAoctq_eoE2g@t14ultra/
> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> ---
>  lib/vdso/Makefile.include | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/lib/vdso/Makefile.include b/lib/vdso/Makefile.include
> index cedbf15f80874d4bb27c097244bc5b11272f261c..18fcc94e4d6bf7abf374c7a953349e7ad75f8a18 100644
> --- a/lib/vdso/Makefile.include
> +++ b/lib/vdso/Makefile.include
> @@ -12,7 +12,12 @@ c-getrandom-$(CONFIG_VDSO_GETRANDOM) := $(addprefix $(GENERIC_VDSO_DIR), getrand
>  #
>  # As a workaround for some GNU ld ports which produce unneeded R_*_NONE
>  # dynamic relocations, ignore R_*_NONE.
> +#
> +# Also validate that no absolute relocations are present in the object files themselves.
>  quiet_cmd_vdso_check = VDSOCHK $@
>        cmd_vdso_check = if $(READELF) -rW $@ | grep -v _NONE | grep -q " R_\w*_"; \
>                        then (echo >&2 "$@: dynamic relocations are not supported"; \
> +                            rm -f $@; /bin/false); fi && \
> +                      if $(READELF) -rW $(filter %.o, $(real-prereqs)) | grep -q " R_\w*_ABS"; \
> +                      then (echo >&2 "$@: absolute relocations are not supported"; \
>                              rm -f $@; /bin/false); fi

Should this check only some sections? I'm getting lot of matches on
debuginfo related sections:

# readelf -rW arch/arm64/kernel/vdso/vgettimeofday.o | awk
'/section.*debug/ {count=10} count {print; count--}'
Relocation section '.rela.debug_info' at offset 0x4fc8 contains 524 entries:
    Offset             Info             Type               Symbol's
Value  Symbol's Name + Addend
0000000000000008  0000000a00000102 R_AARCH64_ABS32
0000000000000000 .debug_abbrev + 0
000000000000000d  0000000f00000102 R_AARCH64_ABS32
0000000000000000 .debug_str + 3b3
0000000000000012  0000001000000102 R_AARCH64_ABS32
0000000000000000 .debug_line_str + 0
0000000000000016  0000001000000102 R_AARCH64_ABS32
0000000000000000 .debug_line_str + 27
000000000000001a  0000000200000101 R_AARCH64_ABS64
0000000000000000 .text + 0
000000000000002a  0000000e00000102 R_AARCH64_ABS32
0000000000000000 .debug_line + 0
0000000000000031  0000000f00000102 R_AARCH64_ABS32
0000000000000000 .debug_str + 2d5
0000000000000038  0000000f00000102 R_AARCH64_ABS32
0000000000000000 .debug_str + 7f0
Relocation section '.rela.debug_loclists' at offset 0x80e8 contains 3 entries:
    Offset             Info             Type               Symbol's
Value  Symbol's Name + Addend
0000000000000504  0000000900000102 R_AARCH64_ABS32
0000000000000000 .debug_info + ab8
0000000000000b3a  0000000900000102 R_AARCH64_ABS32
0000000000000000 .debug_info + 1111
0000000000000bc5  0000000900000102 R_AARCH64_ABS32
0000000000000000 .debug_info + 143e

Relocation section '.rela.debug_aranges' at offset 0x8130 contains 2 entries:
    Offset             Info             Type               Symbol's
Value  Symbol's Name + Addend
0000000000000006  0000000900000102 R_AARCH64_ABS32
0000000000000000 .debug_info + 0
0000000000000010  0000000200000101 R_AARCH64_ABS64
0000000000000000 .text + 0

Relocation section '.rela.debug_line' at offset 0x8160 contains 27 entries:
    Offset             Info             Type               Symbol's
Value  Symbol's Name + Addend
0000000000000022  0000001000000102 R_AARCH64_ABS32
0000000000000000 .debug_line_str + 38
0000000000000026  0000001000000102 R_AARCH64_ABS32
0000000000000000 .debug_line_str + 49
000000000000002a  0000001000000102 R_AARCH64_ABS32
0000000000000000 .debug_line_str + 60
000000000000002e  0000001000000102 R_AARCH64_ABS32
0000000000000000 .debug_line_str + 7a
0000000000000032  0000001000000102 R_AARCH64_ABS32
0000000000000000 .debug_line_str + 98
0000000000000036  0000001000000102 R_AARCH64_ABS32
0000000000000000 .debug_line_str + a7
000000000000003a  0000001000000102 R_AARCH64_ABS32
0000000000000000 .debug_line_str + c2
000000000000003e  0000001000000102 R_AARCH64_ABS32
0000000000000000 .debug_line_str + d8

Regards,
Jan
Re: [PATCH 2/2] vdso: Reject absolute relocations during build
Posted by Thomas Gleixner 9 months, 2 weeks ago
On Tue, Apr 29 2025 at 17:17, Jan Stancek wrote:
> On Tue, Apr 29, 2025 at 2:56 PM Thomas Weißschuh
> <thomas.weissschuh@linutronix.de> wrote:
>>
>> +# Also validate that no absolute relocations are present in the object files themselves.
>>  quiet_cmd_vdso_check = VDSOCHK $@
>>        cmd_vdso_check = if $(READELF) -rW $@ | grep -v _NONE | grep -q " R_\w*_"; \
>>                        then (echo >&2 "$@: dynamic relocations are not supported"; \
>> +                            rm -f $@; /bin/false); fi && \
>> +                      if $(READELF) -rW $(filter %.o, $(real-prereqs)) | grep -q " R_\w*_ABS"; \
>> +                      then (echo >&2 "$@: absolute relocations are not supported"; \
>>                              rm -f $@; /bin/false); fi
>
> Should this check only some sections? I'm getting lot of matches on
> debuginfo related sections:

Hmm. All architecture VDSO Makefiles have -fPIC in CFLAGS except for
arm64, which only adds it in arm64/kernel/vdso32/Makefile but not in
arm64/kernel/vdso/Makefile. Confused.

Thanks,

        tglx
Re: [PATCH 2/2] vdso: Reject absolute relocations during build
Posted by Thomas Weißschuh 9 months, 2 weeks ago
On Wed, Apr 30, 2025 at 09:32:27AM +0200, Thomas Gleixner wrote:
> On Tue, Apr 29 2025 at 17:17, Jan Stancek wrote:
> > On Tue, Apr 29, 2025 at 2:56 PM Thomas Weißschuh
> > <thomas.weissschuh@linutronix.de> wrote:
> >>
> >> +# Also validate that no absolute relocations are present in the object files themselves.
> >>  quiet_cmd_vdso_check = VDSOCHK $@
> >>        cmd_vdso_check = if $(READELF) -rW $@ | grep -v _NONE | grep -q " R_\w*_"; \
> >>                        then (echo >&2 "$@: dynamic relocations are not supported"; \
> >> +                            rm -f $@; /bin/false); fi && \
> >> +                      if $(READELF) -rW $(filter %.o, $(real-prereqs)) | grep -q " R_\w*_ABS"; \
> >> +                      then (echo >&2 "$@: absolute relocations are not supported"; \
> >>                              rm -f $@; /bin/false); fi
> >
> > Should this check only some sections? I'm getting lot of matches on
> > debuginfo related sections:
> 
> Hmm. All architecture VDSO Makefiles have -fPIC in CFLAGS except for
> arm64, which only adds it in arm64/kernel/vdso32/Makefile but not in
> arm64/kernel/vdso/Makefile. Confused.

Unfortunately -fPIC does not help. It generates code that is sufficiently
position independent for regular DSOs, but not the vDSO.

See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120002#c5