mirror of
https://git.yoctoproject.org/poky
synced 2026-02-26 11:29:40 +01:00
CVE-2025-1179-pre.patch is dependency patch for CVE-2025-1179.patch Upstream-Status: Submitted [https://sourceware.org/pipermail/binutils/2025-May/141322.html && https://sourceware.org/pipermail/binutils/2025-May/141321.html] CVE: CVE-2025-1179 cherry picked from upstream commit: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=67e30b15212adc1502b898a1ca224fdf65dc110d https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1d68a49ac5d71b648304f69af978fce0f4413800 (From OE-Core rev: 8f54548f784ef60eaf7fb6b3f539d48b0f7192a3) Signed-off-by: Harish Sadineni <Harish.Sadineni@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
270 lines
7.8 KiB
Diff
270 lines
7.8 KiB
Diff
From 67e30b15212adc1502b898a1ca224fdf65dc110d Mon Sep 17 00:00:00 2001
|
|
From: "H.J. Lu" <hjl.tools@gmail.com>
|
|
Date: Thu, 29 Aug 2024 08:47:00 -0700
|
|
Subject: [PATCH] x86: Check invalid TLS descriptor call TLS descriptor
|
|
call,
|
|
|
|
call *x@tlsdesc(%rax)
|
|
|
|
or
|
|
|
|
call *x@tlsdesc(%eax)
|
|
|
|
calls _dl_tlsdesc_return which expects that RAX/EAX points to the TLS
|
|
descriptor. Update x86 linker to issue an error with or without TLS
|
|
transition.
|
|
|
|
bfd/
|
|
|
|
PR ld/32123
|
|
* elf32-i386.c (elf_i386_check_tls_transition): Move
|
|
R_386_TLS_DESC_CALL to ...
|
|
(elf_i386_tls_transition): Here.
|
|
* elf64-x86-64.c (elf_x86_64_check_tls_transition): Move.
|
|
R_X86_64_TLSDESC_CALL check to ...
|
|
(elf_x86_64_tls_transition): Here.
|
|
|
|
ld/
|
|
|
|
PR ld/32123
|
|
* testsuite/ld-i386/i386.exp: Run tlsgdesc3.
|
|
* testsuite/ld-i386/tlsgdesc3.d: New file.
|
|
* testsuite/ld-x86-64/tlsdesc5.d: Likewise.
|
|
* testsuite/ld-x86-64/x86-64.exp: Run tlsdesc5.
|
|
|
|
(cherry picked from commit:67e30b15212adc1502b898a1ca224fdf65dc110d)
|
|
Upstream-Status: Submitted [https://sourceware.org/pipermail/binutils/2025-May/141321.html]
|
|
CVE: CVE-2025-1179
|
|
|
|
Signed-off-by: Harish Sadineni <Harish.Sadineni@windriver.com>
|
|
---
|
|
bfd/elf32-i386.c | 44 +++++++++++++------
|
|
bfd/elf64-x86-64.c | 71 +++++++++++++++++++------------
|
|
ld/testsuite/ld-i386/i386.exp | 1 +
|
|
ld/testsuite/ld-i386/tlsgdesc3.d | 5 +++
|
|
ld/testsuite/ld-x86-64/tlsdesc5.d | 5 +++
|
|
ld/testsuite/ld-x86-64/x86-64.exp | 1 +
|
|
6 files changed, 86 insertions(+), 41 deletions(-)
|
|
create mode 100644 ld/testsuite/ld-i386/tlsgdesc3.d
|
|
create mode 100644 ld/testsuite/ld-x86-64/tlsdesc5.d
|
|
|
|
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
|
|
index 18a28d2491c..9dea465f721 100644
|
|
--- a/bfd/elf32-i386.c
|
|
+++ b/bfd/elf32-i386.c
|
|
@@ -1039,19 +1039,8 @@ elf_i386_check_tls_transition (asection *sec,
|
|
: elf_x86_tls_error_yes);
|
|
|
|
case R_386_TLS_DESC_CALL:
|
|
- /* Check transition from GDesc access model:
|
|
- call *x@tlsdesc(%eax)
|
|
- */
|
|
- if (offset + 2 <= sec->size)
|
|
- {
|
|
- /* Make sure that it's a call *x@tlsdesc(%eax). */
|
|
- call = contents + offset;
|
|
- return (call[0] == 0xff && call[1] == 0x10
|
|
- ? elf_x86_tls_error_none
|
|
- : elf_x86_tls_error_indirect_call);
|
|
- }
|
|
-
|
|
- return elf_x86_tls_error_yes;
|
|
+ /* It has been checked in elf_i386_tls_transition. */
|
|
+ return elf_x86_tls_error_none;
|
|
|
|
default:
|
|
abort ();
|
|
@@ -1077,6 +1066,8 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd,
|
|
unsigned int to_type = from_type;
|
|
bool check = true;
|
|
unsigned int to_le_type, to_ie_type;
|
|
+ bfd_vma offset;
|
|
+ bfd_byte *call;
|
|
|
|
/* Skip TLS transition for functions. */
|
|
if (h != NULL
|
|
@@ -1098,9 +1089,34 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd,
|
|
|
|
switch (from_type)
|
|
{
|
|
+ case R_386_TLS_DESC_CALL:
|
|
+ /* Check valid GDesc call:
|
|
+ call *x@tlsdesc(%eax)
|
|
+ */
|
|
+ offset = rel->r_offset;
|
|
+ call = NULL;
|
|
+ if (offset + 2 <= sec->size)
|
|
+ {
|
|
+ /* Make sure that it's a call *x@tlsdesc(%eax). */
|
|
+ call = contents + offset;
|
|
+ if (call[0] != 0xff || call[1] != 0x10)
|
|
+ call = NULL;
|
|
+ }
|
|
+
|
|
+ if (call == NULL)
|
|
+ {
|
|
+ _bfd_x86_elf_link_report_tls_transition_error
|
|
+ (info, abfd, sec, symtab_hdr, h, sym, rel,
|
|
+ "R_386_TLS_DESC_CALL", NULL,
|
|
+ elf_x86_tls_error_indirect_call);
|
|
+
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ /* Fall through. */
|
|
+
|
|
case R_386_TLS_GD:
|
|
case R_386_TLS_GOTDESC:
|
|
- case R_386_TLS_DESC_CALL:
|
|
case R_386_TLS_IE_32:
|
|
case R_386_TLS_IE:
|
|
case R_386_TLS_GOTIE:
|
|
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
|
|
index f116e423f61..7af2e607b02 100644
|
|
--- a/bfd/elf64-x86-64.c
|
|
+++ b/bfd/elf64-x86-64.c
|
|
@@ -1409,32 +1409,8 @@ elf_x86_64_check_tls_transition (bfd *abfd,
|
|
: elf_x86_tls_error_yes);
|
|
|
|
case R_X86_64_TLSDESC_CALL:
|
|
- /* Check transition from GDesc access model:
|
|
- call *x@tlsdesc(%rax) <--- LP64 mode.
|
|
- call *x@tlsdesc(%eax) <--- X32 mode.
|
|
- */
|
|
- if (offset + 2 <= sec->size)
|
|
- {
|
|
- unsigned int prefix;
|
|
- call = contents + offset;
|
|
- prefix = 0;
|
|
- if (!ABI_64_P (abfd))
|
|
- {
|
|
- /* Check for call *x@tlsdesc(%eax). */
|
|
- if (call[0] == 0x67)
|
|
- {
|
|
- prefix = 1;
|
|
- if (offset + 3 > sec->size)
|
|
- return elf_x86_tls_error_yes;
|
|
- }
|
|
- }
|
|
- /* Make sure that it's a call *x@tlsdesc(%rax). */
|
|
- return (call[prefix] == 0xff && call[1 + prefix] == 0x10
|
|
- ? elf_x86_tls_error_none
|
|
- : elf_x86_tls_error_indirect_call);
|
|
- }
|
|
-
|
|
- return elf_x86_tls_error_yes;
|
|
+ /* It has been checked in elf_x86_64_tls_transition. */
|
|
+ return elf_x86_tls_error_none;
|
|
|
|
default:
|
|
abort ();
|
|
@@ -1459,6 +1435,8 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
|
|
unsigned int from_type = *r_type;
|
|
unsigned int to_type = from_type;
|
|
bool check = true;
|
|
+ bfd_vma offset;
|
|
+ bfd_byte *call;
|
|
|
|
/* Skip TLS transition for functions. */
|
|
if (h != NULL
|
|
@@ -1468,10 +1446,49 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
|
|
|
|
switch (from_type)
|
|
{
|
|
+ case R_X86_64_TLSDESC_CALL:
|
|
+ /* Check valid GDesc call:
|
|
+ call *x@tlsdesc(%rax) <--- LP64 mode.
|
|
+ call *x@tlsdesc(%eax) <--- X32 mode.
|
|
+ */
|
|
+ offset = rel->r_offset;
|
|
+ call = NULL;
|
|
+ if (offset + 2 <= sec->size)
|
|
+ {
|
|
+ unsigned int prefix;
|
|
+ call = contents + offset;
|
|
+ prefix = 0;
|
|
+ if (!ABI_64_P (abfd))
|
|
+ {
|
|
+ /* Check for call *x@tlsdesc(%eax). */
|
|
+ if (call[0] == 0x67)
|
|
+ {
|
|
+ prefix = 1;
|
|
+ if (offset + 3 > sec->size)
|
|
+ call = NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Make sure that it's a call *x@tlsdesc(%rax). */
|
|
+ if (call != NULL
|
|
+ && (call[prefix] != 0xff || call[1 + prefix] != 0x10))
|
|
+ call = NULL;
|
|
+ }
|
|
+
|
|
+ if (call == NULL)
|
|
+ {
|
|
+ _bfd_x86_elf_link_report_tls_transition_error
|
|
+ (info, abfd, sec, symtab_hdr, h, sym, rel,
|
|
+ "R_X86_64_TLSDESC_CALL", NULL,
|
|
+ elf_x86_tls_error_indirect_call);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ /* Fall through. */
|
|
+
|
|
case R_X86_64_TLSGD:
|
|
case R_X86_64_GOTPC32_TLSDESC:
|
|
case R_X86_64_CODE_4_GOTPC32_TLSDESC:
|
|
- case R_X86_64_TLSDESC_CALL:
|
|
case R_X86_64_GOTTPOFF:
|
|
case R_X86_64_CODE_4_GOTTPOFF:
|
|
case R_X86_64_CODE_6_GOTTPOFF:
|
|
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
|
|
index a8db2c713f3..41e8725d059 100644
|
|
--- a/ld/testsuite/ld-i386/i386.exp
|
|
+++ b/ld/testsuite/ld-i386/i386.exp
|
|
@@ -543,6 +543,7 @@ run_dump_test "pr27998a"
|
|
run_dump_test "pr27998b"
|
|
run_dump_test "tlsgdesc1"
|
|
run_dump_test "tlsgdesc2"
|
|
+run_dump_test "tlsgdesc3"
|
|
|
|
proc undefined_weak {cflags ldflags} {
|
|
set testname "Undefined weak symbol"
|
|
diff --git a/ld/testsuite/ld-i386/tlsgdesc3.d b/ld/testsuite/ld-i386/tlsgdesc3.d
|
|
new file mode 100644
|
|
index 00000000000..f2c29d880f2
|
|
--- /dev/null
|
|
+++ b/ld/testsuite/ld-i386/tlsgdesc3.d
|
|
@@ -0,0 +1,5 @@
|
|
+#source: tlsgdesc2.s
|
|
+#name: TLS GDesc call (indirect CALL)
|
|
+#as: --32
|
|
+#ld: -shared -melf_i386
|
|
+#error: .*: relocation R_386_TLS_DESC_CALL against `foo' must be used in indirect CALL with EAX register only
|
|
diff --git a/ld/testsuite/ld-x86-64/tlsdesc5.d b/ld/testsuite/ld-x86-64/tlsdesc5.d
|
|
new file mode 100644
|
|
index 00000000000..6a0158b44b7
|
|
--- /dev/null
|
|
+++ b/ld/testsuite/ld-x86-64/tlsdesc5.d
|
|
@@ -0,0 +1,5 @@
|
|
+#source: tlsdesc4.s
|
|
+#name: TLS GDesc call (indirect CALL)
|
|
+#as: --64
|
|
+#ld: -shared -melf_x86_64
|
|
+#error: .*: relocation R_X86_64_TLSDESC_CALL against `foo' must be used in indirect CALL with RAX register only
|
|
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
|
|
index 811813466f8..82b0520c52a 100644
|
|
--- a/ld/testsuite/ld-x86-64/x86-64.exp
|
|
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
|
|
@@ -744,6 +744,7 @@ run_dump_test "pr29820"
|
|
run_dump_test "tlsie5"
|
|
run_dump_test "tlsdesc3"
|
|
run_dump_test "tlsdesc4"
|
|
+run_dump_test "tlsdesc5"
|
|
|
|
proc undefined_weak {cflags ldflags} {
|
|
set testname "Undefined weak symbol"
|
|
--
|
|
2.49.0
|
|
|