diff options
| author | Rich Felker <dalias@aerifal.cx> | 2026-05-05 20:34:14 -0400 |
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2026-05-05 20:34:14 -0400 |
| commit | 64f05291ff99ae407801ad7ab44cc4d7f6e0350f (patch) | |
| tree | 8887f74e34b749a6df46da299e1a1700c1fd0e51 /ldso/dynlink.c | |
| parent | bb4b4102461acfbf77da759ca3a6deb555f3da3b (diff) | |
| download | musl-64f05291ff99ae407801ad7ab44cc4d7f6e0350f.tar.gz | |
ldso: fix missing errno code when reporting relro mprotect failure
this code path potentially runs prior to stage 3, with thread-local
storgae and thus errno unavailable. for this reason, commit
63c67053a3e42e9dff788de432f82ff07d4d772a removed the call to the
mprotect function and replaced it with a __syscall operation that
bypasses errno.
however, this left the error message printing (which is only reachable
in stage 3 and thus can safely access errno) with no error code for
the %m format specifier to use.
introduce a new set_errno function pointer that points to a no-op
until stage 3. this is analogous to the error function pointer
introduced in commit d16d7b10997e6f1c224c3de01b43868f0ce2cc3d.
Diffstat (limited to 'ldso/dynlink.c')
| -rw-r--r-- | ldso/dynlink.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 715948f4..10471b23 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -41,6 +41,10 @@ static void error_impl(const char *, ...); static void error_noop(const char *, ...); static void (*error)(const char *, ...) = error_noop; +static void set_errno_impl(int); +static void set_errno_noop(int); +static void (*set_errno)(int) = set_errno_noop; + #define MAXP2(a,b) (-(-(a)&-(b))) #define ALIGN(x,y) ((x)+(y)-1 & -(y)) @@ -1424,6 +1428,7 @@ static void reloc_all(struct dso *p) long ret = __syscall(SYS_mprotect, laddr(p, p->relro_start), p->relro_end-p->relro_start, PROT_READ); if (ret != 0 && ret != -ENOSYS) { + set_errno(-ret); error("Error relocating %s: RELRO protection failed: %m", p->name); if (runtime) longjmp(*rtld_fail, 1); @@ -1825,6 +1830,7 @@ void __dls3(size_t *sp, size_t *auxv) /* Activate error handler function */ error = error_impl; + set_errno = set_errno_impl; /* If the main program was already loaded by the kernel, * AT_PHDR will point to some location other than the dynamic @@ -2437,3 +2443,12 @@ static void error_impl(const char *fmt, ...) static void error_noop(const char *fmt, ...) { } + +static void set_errno_impl(int e) +{ + errno = e; +} + +static void set_errno_noop(int e) +{ +} |
