main/musl: backport relr support patches

This commit is contained in:
psykose 2023-04-18 12:44:13 +00:00
parent 236d538b6b
commit 1507c3c92c
5 changed files with 198 additions and 1 deletions

View File

@ -2,7 +2,7 @@
# Maintainer: Timo Teräs <timo.teras@iki.fi>
pkgname=musl
pkgver=1.2.2
pkgrel=4
pkgrel=5
pkgdesc="the musl c library (libc) implementation"
url="https://musl.libc.org/"
arch="all"
@ -24,6 +24,10 @@ source="musl-$commit.tar.gz::https://git.musl-libc.org/cgit/musl/snapshot/$commi
0001-mallocng-aligned_alloc-check-for-malloc-failure.patch
handle-aux-at_base.patch
syscall-cp-epoll.patch
relr-1.patch
relr-2.patch
relr-3.patch
relr-4.patch
ldconfig
__stack_chk_fail_local.c
@ -174,6 +178,10 @@ f036317426d54efb4df41c08664c8513d3991408b20f4c74220c8b0324d2e96a97094851ea225e36
a4911136e2d93b08cf4831fadfb9f01e65a5978bd6d289ce4a127d5afca048225ab254990d73d39aa744db81b9456fd91e282b338d45d41ec036d44fd64acacd 0001-mallocng-aligned_alloc-check-for-malloc-failure.patch
a76f79b801497ad994746cf82bb6eaf86f9e1ae646e6819fbae8532a7f4eee53a96ac1d4e789ec8f66aea2a68027b0597f7a579b3369e01258da8accfce41370 handle-aux-at_base.patch
d256ba7857c98d39b86aa73674eda5d45ab8134dde3fac2bc48ebb6ba9a824c20c43f2cdc6af54d2a45c162d1e4ec6517c36400992bba10496bcc51b374cbcd0 syscall-cp-epoll.patch
8ebcde1e07819de208ab89ed0a71fdcc67a5b1cecec5aa19a92bc9f4f3c2708a9ff1528370089de0b71e9ec3b2e08dfa49694db433ac190ba055aa112ae12bde relr-1.patch
38b40ebedf57ba05ba14807a55a26261eeca8b6226a90a7aaebaaa31bae0bb7f5b98e0ce3ed727b704b828c9e509a21745f3e089585f8dea7092be164ec9d908 relr-2.patch
9dc41f682887ef9a7b00253f576d0b738936c20d9bc5a54fa96552a82a2f056f0111936ad9778b96745befd6a660276618b4e05bef3c7f52d8c2a9e6d41e386c relr-3.patch
ee6ec5943df10597af0df3d6f792720a22d2070debb6933656a10a906725d1170c28c32ba8ad53efc72e77bd1d97efdbd3c80e91eddb856f377e917ff14ae8f3 relr-4.patch
8d3a2d5315fc56fee7da9abb8b89bb38c6046c33d154c10d168fb35bfde6b0cf9f13042a3bceee34daf091bc409d699223735dcf19f382eeee1f6be34154f26f ldconfig
062bb49fa54839010acd4af113e20f7263dde1c8a2ca359b5fb2661ef9ed9d84a0f7c3bc10c25dcfa10bb3c5a4874588dff636ac43d5dbb3d748d75400756d0b __stack_chk_fail_local.c
0d80f37b34a35e3d14b012257c50862dfeb9d2c81139ea2dfa101d981d093b009b9fa450ba27a708ac59377a48626971dfc58e20a3799084a65777a0c32cbc7d getconf.c

100
main/musl/relr-1.patch Normal file
View File

@ -0,0 +1,100 @@
From d32dadd60efb9d3b255351a3b532f8e4c3dd0db1 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i@maskray.me>
Date: Tue, 2 Aug 2022 17:24:47 -0400
Subject: ldso: support DT_RELR relative relocation format
this resolves DT_RELR relocations in non-ldso, dynamic-linked objects.
---
include/elf.h | 8 ++++++--
ldso/dynlink.c | 21 ++++++++++++++++++++-
src/internal/dynlink.h | 2 +-
3 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/include/elf.h b/include/elf.h
index 86e2f0bb..9e980a29 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -385,7 +385,8 @@ typedef struct {
#define SHT_PREINIT_ARRAY 16
#define SHT_GROUP 17
#define SHT_SYMTAB_SHNDX 18
-#define SHT_NUM 19
+#define SHT_RELR 19
+#define SHT_NUM 20
#define SHT_LOOS 0x60000000
#define SHT_GNU_ATTRIBUTES 0x6ffffff5
#define SHT_GNU_HASH 0x6ffffff6
@@ -754,7 +755,10 @@ typedef struct {
#define DT_PREINIT_ARRAY 32
#define DT_PREINIT_ARRAYSZ 33
#define DT_SYMTAB_SHNDX 34
-#define DT_NUM 35
+#define DT_RELRSZ 35
+#define DT_RELR 36
+#define DT_RELRENT 37
+#define DT_NUM 38
#define DT_LOOS 0x6000000d
#define DT_HIOS 0x6ffff000
#define DT_LOPROC 0x70000000
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index cc677952..e92f03cb 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -210,7 +210,8 @@ static void decode_vec(size_t *v, size_t *a, size_t cnt)
size_t i;
for (i=0; i<cnt; i++) a[i] = 0;
for (; v[0]; v+=2) if (v[0]-1<cnt-1) {
- a[0] |= 1UL<<v[0];
+ if (v[0] < 8*sizeof(long))
+ a[0] |= 1UL<<v[0];
a[v[0]] = v[1];
}
}
@@ -515,6 +516,23 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
}
}
+static void do_relr_relocs(struct dso *dso, size_t *relr, size_t relr_size)
+{
+ unsigned char *base = dso->base;
+ size_t *reloc_addr;
+ for (; relr_size; relr++, relr_size-=sizeof(size_t))
+ if ((relr[0]&1) == 0) {
+ reloc_addr = laddr(dso, relr[0]);
+ *reloc_addr++ += (size_t)base;
+ } else {
+ int i = 0;
+ for (size_t bitmap=relr[0]; (bitmap>>=1); i++)
+ if (bitmap&1)
+ reloc_addr[i] += (size_t)base;
+ reloc_addr += 8*sizeof(size_t)-1;
+ }
+}
+
static void redo_lazy_relocs()
{
struct dso *p = lazy_head, *next;
@@ -1357,6 +1375,7 @@ static void reloc_all(struct dso *p)
2+(dyn[DT_PLTREL]==DT_RELA));
do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2);
do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3);
+ do_relr_relocs(p, laddr(p, dyn[DT_RELR]), dyn[DT_RELRSZ]);
if (head != &ldso && p->relro_start != p->relro_end) {
long ret = __syscall(SYS_mprotect, laddr(p, p->relro_start),
diff --git a/src/internal/dynlink.h b/src/internal/dynlink.h
index 51c0639f..830354eb 100644
--- a/src/internal/dynlink.h
+++ b/src/internal/dynlink.h
@@ -93,7 +93,7 @@ struct fdpic_dummy_loadmap {
#endif
#define AUX_CNT 32
-#define DYN_CNT 32
+#define DYN_CNT 37
typedef void (*stage2_func)(unsigned char *, size_t *);
--
cgit v1.2.1

31
main/musl/relr-2.patch Normal file
View File

@ -0,0 +1,31 @@
From bf99258564fd5b58974d93201ab61506eb8cb03e Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Tue, 2 Aug 2022 17:29:01 -0400
Subject: ldso: process RELR only for non-FDPIC archs
the way RELR is applied is not a meaningful operation for FDPIC (there
is no single "base" address). it seems unlikely RELR would ever be
added for FDPIC, but if it ever is, the behavior and possibly data
format will need to be different, so guard against calling the
non-FDPIC code.
---
ldso/dynlink.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index e92f03cb..fd09ca69 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -1375,7 +1375,8 @@ static void reloc_all(struct dso *p)
2+(dyn[DT_PLTREL]==DT_RELA));
do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2);
do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3);
- do_relr_relocs(p, laddr(p, dyn[DT_RELR]), dyn[DT_RELRSZ]);
+ if (!DL_FDPIC)
+ do_relr_relocs(p, laddr(p, dyn[DT_RELR]), dyn[DT_RELRSZ]);
if (head != &ldso && p->relro_start != p->relro_end) {
long ret = __syscall(SYS_mprotect, laddr(p, p->relro_start),
--
cgit v1.2.1

46
main/musl/relr-3.patch Normal file
View File

@ -0,0 +1,46 @@
From 6f3ead0ae16deb9f0004b275e29a276c9712ee3c Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Mon, 12 Sep 2022 08:30:36 -0400
Subject: process DT_RELR relocations in ldso-startup/static-pie
commit d32dadd60efb9d3b255351a3b532f8e4c3dd0db1 added DT_RELR
processing for programs and shared libraries processed by the dynamic
linker, but left them unsupported in the dynamic linker itseld and in
static pie binaries, which self-relocate via code in dlstart.c.
add the equivalent processing to this code path so that there are not
arbitrary restrictions on where the new packed relative relocation
form can be used.
---
ldso/dlstart.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/ldso/dlstart.c b/ldso/dlstart.c
index 20d50f2c..259f5e18 100644
--- a/ldso/dlstart.c
+++ b/ldso/dlstart.c
@@ -140,6 +140,21 @@ hidden void _dlstart_c(size_t *sp, size_t *dynv)
size_t *rel_addr = (void *)(base + rel[0]);
*rel_addr = base + rel[2];
}
+
+ rel = (void *)(base+dyn[DT_RELR]);
+ rel_size = dyn[DT_RELRSZ];
+ size_t *relr_addr = 0;
+ for (; rel_size; rel++, rel_size-=sizeof(size_t)) {
+ if ((rel[0]&1) == 0) {
+ relr_addr = (void *)(base + rel[0]);
+ *relr_addr++ += base;
+ } else {
+ for (size_t i=0, bitmap=rel[0]; bitmap>>=1; i++)
+ if (bitmap&1)
+ relr_addr[i] += base;
+ relr_addr += 8*sizeof(size_t)-1;
+ }
+ }
#endif
stage2_func dls2;
--
cgit v1.2.1

12
main/musl/relr-4.patch Normal file
View File

@ -0,0 +1,12 @@
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 7b47b163..753de91d 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -552,6 +552,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
static void do_relr_relocs(struct dso *dso, size_t *relr, size_t relr_size)
{
+ if (dso == &ldso) return; // self-relocation already done a entry point
unsigned char *base = dso->base;
size_t *reloc_addr;
for (; relr_size; relr++, relr_size-=sizeof(size_t))