mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] Static linking is broken after creation of DT_TEXTREL segment
@ 2020-01-29 18:41 Андрей Аладьев
  2020-01-29 19:19 ` Markus Wichmann
  2020-01-29 20:53 ` Rich Felker
  0 siblings, 2 replies; 26+ messages in thread
From: Андрей Аладьев @ 2020-01-29 18:41 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 3516 bytes --]

Hello. Please use the following docker image
"puchuu/test_x86_64-gentoo-linux-musl". I will write here complete steps so
everyone can reproduce this issue.

docker run -it puchuu/test_x86_64-gentoo-linux-musl bash
env-update && source /etc/profile
echo "dev-libs/gmp static-libs" > /etc/portage/package.use/gmp
MAKEOPTS='-j16' emerge -v dev-libs/gmp
cd /tmp && wget "
https://raw.githubusercontent.com/andrew-aladev/lzws/master/cmake/checks/GMP/main.c
"

gcc main.c -static -lgmp -o main && ./main
We can see that "-static -lgmp" works perfect.

gcc main.c /usr/lib/libgmp.a -o main && ./main
/usr/lib/gcc/x86_64-gentoo-linux-musl/9.2.0/../../../../x86_64-gentoo-linux-musl/bin/ld:
/usr/lib/libgmp.a(bdiv_q_1.o): warning: relocation against
`__gmp_binvert_limb_table' in read-only section `.text'
/usr/lib/gcc/x86_64-gentoo-linux-musl/9.2.0/../../../../x86_64-gentoo-linux-musl/bin/ld:
warning: creating a DT_TEXTREL in object
Segmentation fault (core dumped)
We can see that direct usage of "/usr/lib/libgmp.a" provided DT_TEXTREL
segment.

MAKEOPTS='-j16' emerge -v gdb dev-vcs/git
CFLAGS='-O0 -g -ggdb -ggdb3' CXXFLAGS='-O0 -g -ggdb -ggdb3'
FEATURES='nostrip' MAKEOPTS='-j16' emerge -v musl gmp
git clone git://git.musl-libc.org/musl --depth=1 --single-branch -b
"v1.1.24"
gcc -O0 -g -ggdb -ggdb3 main.c /usr/lib/libgmp.a -o main && gdb -ex=run -d
musl ./main

Program received signal SIGSEGV, Segmentation fault.
0x00007fe2f8c4f231 in do_relocs (dso=0x7fe2f8c8eb40 <app>,
rel=0x55af0a0cd568, rel_size=456, stride=3) at ldso/dynlink.c:423
423                             *reloc_addr = (size_t)base + addend;
(gdb) where
#0  0x00007fe2f8c4f231 in do_relocs (dso=0x7fe2f8c8eb40 <app>,
rel=0x55af0a0cd568, rel_size=456, stride=3) at ldso/dynlink.c:423
#1  0x00007fe2f8c51e60 in reloc_all (p=0x7fe2f8c8eb40 <app>) at
ldso/dynlink.c:1328
#2  0x00007fe2f8c53a03 in __dls3 (sp=0x7ffc82457260) at ldso/dynlink.c:1906
#3  0x00007fe2f8c52de6 in __dls2b (sp=0x7ffc82457260) at ldso/dynlink.c:1672
#4  0x00007fe2f8c52d4e in __dls2 (base=0x7fe2f8bba000
"\177ELF\002\001\001", sp=0x7ffc82457260) at ldso/dynlink.c:1650
#5  0x00007fe2f8c4e5a0 in _dlstart_c (sp=0x7ffc82457260,
dynv=0x7fe2f8c8be20) at ldso/dlstart.c:147
#6  0x00007fe2f8c4e246 in _dlstart () from /lib/ld-musl-x86_64.so.1
#7  0x0000000000000001 in ?? ()
#8  0x00007ffc82458635 in ?? ()
#9  0x0000000000000000 in ?? ()

(gdb) info locals
base = 0x561041462000 "\177ELF\002\001\001"
syms = 0x5610414622c8
strings = 0x561041462478 ""
sym = 0x0
name = 0x5610414624f8 "free"
ctx = 0x7f9eea640b40 <app>
type = 8
sym_index = 0
def = {sym = 0x0, dso = 0x7f9eea640b40 <app>}
reloc_addr = 0x56104147cf79 <__gmpn_bdiv_q_1+25>
sym_val = 0
tls_val = 0
addend = 131264
skip_relative = 0
reuse_addends = 0
save_slot = 0

(gdb) p laddr(dso, rel[0])
$27 = (void *) 0x56104147cf79 <__gmpn_bdiv_q_1+25>

(gdb) p dso->loadmap
$28 = (struct fdpic_loadmap *) 0x0

(gdb) p (dso->base + rel[0])
$29 = (unsigned char *) 0x56104147cf79 <__gmpn_bdiv_q_1+25> "\300"

We can see that "laddr" provided pointer to "dso->base + rel[0]", than
switch tried to override it's value and segfault appeared. Pointer is
wrong, most likely readonly.

You can replace "gcc" with "clang" and everything will be the same. Updated
binutils to most recent version 2.33.1 and rebuilt toolchain - nothing
changed. Pointer is still invalid and SEGV_ACCERR appears.

So I think that bug is inside musl itself. Glibc container is the same
situation works fine. I see no way to create a workaround for this issue.

[-- Attachment #2: Type: text/html, Size: 4589 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 18:41 [musl] Static linking is broken after creation of DT_TEXTREL segment Андрей Аладьев
@ 2020-01-29 19:19 ` Markus Wichmann
  2020-01-29 19:38   ` Markus Wichmann
  2020-01-29 20:08   ` Андрей Аладьев
  2020-01-29 20:53 ` Rich Felker
  1 sibling, 2 replies; 26+ messages in thread
From: Markus Wichmann @ 2020-01-29 19:19 UTC (permalink / raw)
  To: musl

On Wed, Jan 29, 2020 at 09:41:46PM +0300, Андрей Аладьев wrote:
> gcc main.c /usr/lib/libgmp.a -o main && ./main

Ooh boy, why would you do this? When there's a perfectly good -lgmp just
waiting for you.

> warning: creating a DT_TEXTREL in object

The warning is justified, you usually do not want to do this. With a
TEXTREL, the code has to be mapped as writable, so now programming
errors and exploits can change the executable code.

> We can see that "laddr" provided pointer to "dso->base + rel[0]", than
> switch tried to override it's value and segfault appeared. Pointer is
> wrong, most likely readonly.
>

Pointer is correct, but memory should have been mapped writable. More on
this in a bit.

> You can replace "gcc" with "clang" and everything will be the same. Updated
> binutils to most recent version 2.33.1 and rebuilt toolchain - nothing
> changed. Pointer is still invalid and SEGV_ACCERR appears.
>

Of course. The issue is a relocation inside a read-only segment.
Binutils and compiler are not malfunctioning.

> So I think that bug is inside musl itself. Glibc container is the same
> situation works fine. I see no way to create a workaround for this issue.

Well, the remedy is obvious: Get rid of the TEXTREL. It is usually
caused by bad assembly source code, and fixable with only minor
knowledge of the details. Consult the search engine of your least
distrust for more information on this.

Regarding the actual problem though, the problem here is that DT_TEXTREL
is handled only in map_library(), so it is not handled for kernel mapped
DSOs. Which isn't a problem for libc or the VDSO, but the app itself
might be TEXTREL (and is, in this case), and that isn't handled. How,
though? Iterate over the apps PHDRs and remove write protection from all
RO segments?

And one more question: Since musl resolves all relocations immediately,
couldn't we write-protect TEXTREL modules after relocating them?
Provided no unresolved relocations remain, of course.

Ciao,
Markus

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 19:19 ` Markus Wichmann
@ 2020-01-29 19:38   ` Markus Wichmann
  2020-01-29 20:48     ` Rich Felker
  2020-01-29 20:08   ` Андрей Аладьев
  1 sibling, 1 reply; 26+ messages in thread
From: Markus Wichmann @ 2020-01-29 19:38 UTC (permalink / raw)
  To: musl

On Wed, Jan 29, 2020 at 08:19:46PM +0100, Markus Wichmann wrote:
> On Wed, Jan 29, 2020 at 09:41:46PM +0300, Андрей Аладьев wrote:
> > gcc main.c /usr/lib/libgmp.a -o main && ./main
>
> Ooh boy, why would you do this? When there's a perfectly good -lgmp just
> waiting for you.
>

To expand upon this: libgmp makes sure not to create TEXTRELs if
compiling for PIC. The function in question uses the m4 macro LEA, which
picks the correct code for either situation. Using libgmp.a explicitly
here means you told the code it would be running statically compiled and
then used it for dynamic compilation, anyway.

Ciao,
Markus

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 19:19 ` Markus Wichmann
  2020-01-29 19:38   ` Markus Wichmann
@ 2020-01-29 20:08   ` Андрей Аладьев
  2020-01-30 17:02     ` Markus Wichmann
  1 sibling, 1 reply; 26+ messages in thread
From: Андрей Аладьев @ 2020-01-29 20:08 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 3671 bytes --]

> Ooh boy, why would you do this? When there's a perfectly good -lgmp just
waiting for you.

Usage of "/usr/lib/libgmp.a" directly is not forbidden by any toolchain or
build system. Moreover it is recommended by cmake. You can google for
"target_link_libraries( site:github.com" and found millions of software
that uses something like:

find_library(EXTERNAL_LIB)
target_link_libraries(something ${EXTERNAL_LIB_FOUND})

> The warning is justified, you usually do not want to do this. With a
TEXTREL, the code has to be mapped as writable, so now programming errors
and exploits can change the executable code.

This is warning from ld, not from musl. Segfault is not an acceptable
message from libc. Libc should not try to write into readonly pointer.

> Well, the remedy is obvious: Get rid of the TEXTREL.

Yes, I've found a workaround: "USE='-asm' emerge -v1 gmp", assembly is
broken, will report it to gmp upstream. But this is not a fix for the issue.

> Iterate over the apps PHDRs and remove write protection from all RO
segments?

So libc knows that file is mapped as readonly and should not try to write
into readonly pointers. Libc can do the following:

1. Ignore impossible relocations.
2. Add a warning to stderr and still ignore impossible relocations.
3. do abort, user will receive SIGABRT and understand that he uses libc in
a wrong way.

Segfault is not an acceptable answer.

Thank you.

ср, 29 янв. 2020 г. в 22:20, Markus Wichmann <nullplan@gmx.net>:

> On Wed, Jan 29, 2020 at 09:41:46PM +0300, Андрей Аладьев wrote:
> > gcc main.c /usr/lib/libgmp.a -o main && ./main
>
> Ooh boy, why would you do this? When there's a perfectly good -lgmp just
> waiting for you.
>
> > warning: creating a DT_TEXTREL in object
>
> The warning is justified, you usually do not want to do this. With a
> TEXTREL, the code has to be mapped as writable, so now programming
> errors and exploits can change the executable code.
>
> > We can see that "laddr" provided pointer to "dso->base + rel[0]", than
> > switch tried to override it's value and segfault appeared. Pointer is
> > wrong, most likely readonly.
> >
>
> Pointer is correct, but memory should have been mapped writable. More on
> this in a bit.
>
> > You can replace "gcc" with "clang" and everything will be the same.
> Updated
> > binutils to most recent version 2.33.1 and rebuilt toolchain - nothing
> > changed. Pointer is still invalid and SEGV_ACCERR appears.
> >
>
> Of course. The issue is a relocation inside a read-only segment.
> Binutils and compiler are not malfunctioning.
>
> > So I think that bug is inside musl itself. Glibc container is the same
> > situation works fine. I see no way to create a workaround for this issue.
>
> Well, the remedy is obvious: Get rid of the TEXTREL. It is usually
> caused by bad assembly source code, and fixable with only minor
> knowledge of the details. Consult the search engine of your least
> distrust for more information on this.
>
> Regarding the actual problem though, the problem here is that DT_TEXTREL
> is handled only in map_library(), so it is not handled for kernel mapped
> DSOs. Which isn't a problem for libc or the VDSO, but the app itself
> might be TEXTREL (and is, in this case), and that isn't handled. How,
> though? Iterate over the apps PHDRs and remove write protection from all
> RO segments?
>
> And one more question: Since musl resolves all relocations immediately,
> couldn't we write-protect TEXTREL modules after relocating them?
> Provided no unresolved relocations remain, of course.
>
> Ciao,
> Markus
>

[-- Attachment #2: Type: text/html, Size: 4516 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 19:38   ` Markus Wichmann
@ 2020-01-29 20:48     ` Rich Felker
  0 siblings, 0 replies; 26+ messages in thread
From: Rich Felker @ 2020-01-29 20:48 UTC (permalink / raw)
  To: musl

On Wed, Jan 29, 2020 at 08:38:10PM +0100, Markus Wichmann wrote:
> On Wed, Jan 29, 2020 at 08:19:46PM +0100, Markus Wichmann wrote:
> > On Wed, Jan 29, 2020 at 09:41:46PM +0300, Андрей Аладьев wrote:
> > > gcc main.c /usr/lib/libgmp.a -o main && ./main
> >
> > Ooh boy, why would you do this? When there's a perfectly good -lgmp just
> > waiting for you.
> >
> 
> To expand upon this: libgmp makes sure not to create TEXTRELs if
> compiling for PIC. The function in question uses the m4 macro LEA, which
> picks the correct code for either situation. Using libgmp.a explicitly
> here means you told the code it would be running statically compiled and
> then used it for dynamic compilation, anyway.

This is a bug in gmp -- static libraries can be used in (static or
dynamic linked) PIE executables, and therefore should be compatible
with being built as PIC.

Rich

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 18:41 [musl] Static linking is broken after creation of DT_TEXTREL segment Андрей Аладьев
  2020-01-29 19:19 ` Markus Wichmann
@ 2020-01-29 20:53 ` Rich Felker
  2020-01-29 21:10   ` Szabolcs Nagy
  2020-01-29 21:14   ` Андрей Аладьев
  1 sibling, 2 replies; 26+ messages in thread
From: Rich Felker @ 2020-01-29 20:53 UTC (permalink / raw)
  To: musl

On Wed, Jan 29, 2020 at 09:41:46PM +0300, Андрей Аладьев wrote:
> Hello. Please use the following docker image
> "puchuu/test_x86_64-gentoo-linux-musl". I will write here complete steps so
> everyone can reproduce this issue.
> 
> docker run -it puchuu/test_x86_64-gentoo-linux-musl bash
> env-update && source /etc/profile
> echo "dev-libs/gmp static-libs" > /etc/portage/package.use/gmp
> MAKEOPTS='-j16' emerge -v dev-libs/gmp
> cd /tmp && wget "
> https://raw.githubusercontent.com/andrew-aladev/lzws/master/cmake/checks/GMP/main.c
> "
> 
> gcc main.c -static -lgmp -o main && ./main
> We can see that "-static -lgmp" works perfect.
> 
> gcc main.c /usr/lib/libgmp.a -o main && ./main
> /usr/lib/gcc/x86_64-gentoo-linux-musl/9.2.0/../../../../x86_64-gentoo-linux-musl/bin/ld:
> /usr/lib/libgmp.a(bdiv_q_1.o): warning: relocation against
> `__gmp_binvert_limb_table' in read-only section `.text'
> /usr/lib/gcc/x86_64-gentoo-linux-musl/9.2.0/../../../../x86_64-gentoo-linux-musl/bin/ld:
> warning: creating a DT_TEXTREL in object
> Segmentation fault (core dumped)
> We can see that direct usage of "/usr/lib/libgmp.a" provided DT_TEXTREL
> segment.
> 
> MAKEOPTS='-j16' emerge -v gdb dev-vcs/git
> CFLAGS='-O0 -g -ggdb -ggdb3' CXXFLAGS='-O0 -g -ggdb -ggdb3'
> FEATURES='nostrip' MAKEOPTS='-j16' emerge -v musl gmp
> git clone git://git.musl-libc.org/musl --depth=1 --single-branch -b
> "v1.1.24"
> gcc -O0 -g -ggdb -ggdb3 main.c /usr/lib/libgmp.a -o main && gdb -ex=run -d
> musl ./main
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x00007fe2f8c4f231 in do_relocs (dso=0x7fe2f8c8eb40 <app>,
> rel=0x55af0a0cd568, rel_size=456, stride=3) at ldso/dynlink.c:423
> 423                             *reloc_addr = (size_t)base + addend;
> (gdb) where
> #0  0x00007fe2f8c4f231 in do_relocs (dso=0x7fe2f8c8eb40 <app>,
> rel=0x55af0a0cd568, rel_size=456, stride=3) at ldso/dynlink.c:423
> #1  0x00007fe2f8c51e60 in reloc_all (p=0x7fe2f8c8eb40 <app>) at
> ldso/dynlink.c:1328
> #2  0x00007fe2f8c53a03 in __dls3 (sp=0x7ffc82457260) at ldso/dynlink.c:1906
> #3  0x00007fe2f8c52de6 in __dls2b (sp=0x7ffc82457260) at ldso/dynlink.c:1672
> #4  0x00007fe2f8c52d4e in __dls2 (base=0x7fe2f8bba000
> "\177ELF\002\001\001", sp=0x7ffc82457260) at ldso/dynlink.c:1650
> #5  0x00007fe2f8c4e5a0 in _dlstart_c (sp=0x7ffc82457260,
> dynv=0x7fe2f8c8be20) at ldso/dlstart.c:147
> #6  0x00007fe2f8c4e246 in _dlstart () from /lib/ld-musl-x86_64.so.1
> #7  0x0000000000000001 in ?? ()
> #8  0x00007ffc82458635 in ?? ()
> #9  0x0000000000000000 in ?? ()
> 
> (gdb) info locals
> base = 0x561041462000 "\177ELF\002\001\001"
> syms = 0x5610414622c8
> strings = 0x561041462478 ""
> sym = 0x0
> name = 0x5610414624f8 "free"
> ctx = 0x7f9eea640b40 <app>
> type = 8
> sym_index = 0
> def = {sym = 0x0, dso = 0x7f9eea640b40 <app>}
> reloc_addr = 0x56104147cf79 <__gmpn_bdiv_q_1+25>
> sym_val = 0
> tls_val = 0
> addend = 131264
> skip_relative = 0
> reuse_addends = 0
> save_slot = 0
> 
> (gdb) p laddr(dso, rel[0])
> $27 = (void *) 0x56104147cf79 <__gmpn_bdiv_q_1+25>
> 
> (gdb) p dso->loadmap
> $28 = (struct fdpic_loadmap *) 0x0
> 
> (gdb) p (dso->base + rel[0])
> $29 = (unsigned char *) 0x56104147cf79 <__gmpn_bdiv_q_1+25> "\300"
> 
> We can see that "laddr" provided pointer to "dso->base + rel[0]", than
> switch tried to override it's value and segfault appeared. Pointer is
> wrong, most likely readonly.
> 
> You can replace "gcc" with "clang" and everything will be the same. Updated
> binutils to most recent version 2.33.1 and rebuilt toolchain - nothing
> changed. Pointer is still invalid and SEGV_ACCERR appears.
> 
> So I think that bug is inside musl itself. Glibc container is the same
> situation works fine. I see no way to create a workaround for this issue.

musl only has limited support for TEXTRELs as a legacy feature, and
only on some archs. It does not support them in PIE executables or
other "new settings".

I think what you're hitting is a somewhat-known issue in libgmp where
it uses PIC-incompatible code for the .a library but not for the .so.
There is no good reason for it to do this; the PIC-compatible code is
just as efficient and should always be used.

I'm not sure if there's a published patch for this issue. One solution
is using --disable-asm or whatever the option is called to turn off
the PIC-incompatible asm. But if you want the performance it would be
preferable to fix it in some other way.

An easy workaround if you don't need PIE is just linking with -no-pie.

Rich

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 20:53 ` Rich Felker
@ 2020-01-29 21:10   ` Szabolcs Nagy
  2020-01-29 21:35     ` Андрей Аладьев
  2020-01-29 21:14   ` Андрей Аладьев
  1 sibling, 1 reply; 26+ messages in thread
From: Szabolcs Nagy @ 2020-01-29 21:10 UTC (permalink / raw)
  To: musl

* Rich Felker <dalias@libc.org> [2020-01-29 15:53:30 -0500]:
> On Wed, Jan 29, 2020 at 09:41:46PM +0300, Андрей Аладьев wrote:
> > So I think that bug is inside musl itself. Glibc container is the same
> > situation works fine. I see no way to create a workaround for this issue.
> 
> musl only has limited support for TEXTRELs as a legacy feature, and
> only on some archs. It does not support them in PIE executables or
> other "new settings".

i would like to see why this works on glibc.

glibc can process some text relocs but even then
the elf image will not be shared when multiple
instances of the same binary are executed
potentially wasting a lot of ram and icache.

so i don't think the glibc behaviour is desirable.

if the glibc binary does not have textrel (it can
be checked using readelf -d binary) it would be
nice to know why.

i'm also surprised that it was only a warning,
i think gcc default pie toolchain passes -z text
nowadays exactly to make this a link time failure.
this is probably a gentoo toolchain bug.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 20:53 ` Rich Felker
  2020-01-29 21:10   ` Szabolcs Nagy
@ 2020-01-29 21:14   ` Андрей Аладьев
  2020-01-29 21:43     ` Rich Felker
  1 sibling, 1 reply; 26+ messages in thread
From: Андрей Аладьев @ 2020-01-29 21:14 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 5718 bytes --]

Thank you, I will definitely report this issue to gmp or provide more
information under existing one. Please see here:

if (dso == &ldso) {
  /* Only ldso's REL table needs addend saving/reuse. */
  if (rel == apply_addends_to)
    reuse_addends = 1;
  skip_relative = 1;
}

if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue;

Musl already has "skip_relative" flag. This flag can be improved like:

# ifdef SKIP_RELLOCATION_IN_READONLY_MODE
if (readonly_mode) {
  skip_relative = 1;
}
# endif

if (IS_RELATIVE(rel[1], dso->syms)) {
  if (skip_relative) {
    continue;
  } else if (readonly_mode) {
    error("Error it is not possible to make relocations in readonly mode");
    a_crash();
  }
}

It will make musl more stronger and user friendlier.


ср, 29 янв. 2020 г. в 23:53, Rich Felker <dalias@libc.org>:

> On Wed, Jan 29, 2020 at 09:41:46PM +0300, Андрей Аладьев wrote:
> > Hello. Please use the following docker image
> > "puchuu/test_x86_64-gentoo-linux-musl". I will write here complete steps
> so
> > everyone can reproduce this issue.
> >
> > docker run -it puchuu/test_x86_64-gentoo-linux-musl bash
> > env-update && source /etc/profile
> > echo "dev-libs/gmp static-libs" > /etc/portage/package.use/gmp
> > MAKEOPTS='-j16' emerge -v dev-libs/gmp
> > cd /tmp && wget "
> >
> https://raw.githubusercontent.com/andrew-aladev/lzws/master/cmake/checks/GMP/main.c
> > "
> >
> > gcc main.c -static -lgmp -o main && ./main
> > We can see that "-static -lgmp" works perfect.
> >
> > gcc main.c /usr/lib/libgmp.a -o main && ./main
> >
> /usr/lib/gcc/x86_64-gentoo-linux-musl/9.2.0/../../../../x86_64-gentoo-linux-musl/bin/ld:
> > /usr/lib/libgmp.a(bdiv_q_1.o): warning: relocation against
> > `__gmp_binvert_limb_table' in read-only section `.text'
> >
> /usr/lib/gcc/x86_64-gentoo-linux-musl/9.2.0/../../../../x86_64-gentoo-linux-musl/bin/ld:
> > warning: creating a DT_TEXTREL in object
> > Segmentation fault (core dumped)
> > We can see that direct usage of "/usr/lib/libgmp.a" provided DT_TEXTREL
> > segment.
> >
> > MAKEOPTS='-j16' emerge -v gdb dev-vcs/git
> > CFLAGS='-O0 -g -ggdb -ggdb3' CXXFLAGS='-O0 -g -ggdb -ggdb3'
> > FEATURES='nostrip' MAKEOPTS='-j16' emerge -v musl gmp
> > git clone git://git.musl-libc.org/musl --depth=1 --single-branch -b
> > "v1.1.24"
> > gcc -O0 -g -ggdb -ggdb3 main.c /usr/lib/libgmp.a -o main && gdb -ex=run
> -d
> > musl ./main
> >
> > Program received signal SIGSEGV, Segmentation fault.
> > 0x00007fe2f8c4f231 in do_relocs (dso=0x7fe2f8c8eb40 <app>,
> > rel=0x55af0a0cd568, rel_size=456, stride=3) at ldso/dynlink.c:423
> > 423                             *reloc_addr = (size_t)base + addend;
> > (gdb) where
> > #0  0x00007fe2f8c4f231 in do_relocs (dso=0x7fe2f8c8eb40 <app>,
> > rel=0x55af0a0cd568, rel_size=456, stride=3) at ldso/dynlink.c:423
> > #1  0x00007fe2f8c51e60 in reloc_all (p=0x7fe2f8c8eb40 <app>) at
> > ldso/dynlink.c:1328
> > #2  0x00007fe2f8c53a03 in __dls3 (sp=0x7ffc82457260) at
> ldso/dynlink.c:1906
> > #3  0x00007fe2f8c52de6 in __dls2b (sp=0x7ffc82457260) at
> ldso/dynlink.c:1672
> > #4  0x00007fe2f8c52d4e in __dls2 (base=0x7fe2f8bba000
> > "\177ELF\002\001\001", sp=0x7ffc82457260) at ldso/dynlink.c:1650
> > #5  0x00007fe2f8c4e5a0 in _dlstart_c (sp=0x7ffc82457260,
> > dynv=0x7fe2f8c8be20) at ldso/dlstart.c:147
> > #6  0x00007fe2f8c4e246 in _dlstart () from /lib/ld-musl-x86_64.so.1
> > #7  0x0000000000000001 in ?? ()
> > #8  0x00007ffc82458635 in ?? ()
> > #9  0x0000000000000000 in ?? ()
> >
> > (gdb) info locals
> > base = 0x561041462000 "\177ELF\002\001\001"
> > syms = 0x5610414622c8
> > strings = 0x561041462478 ""
> > sym = 0x0
> > name = 0x5610414624f8 "free"
> > ctx = 0x7f9eea640b40 <app>
> > type = 8
> > sym_index = 0
> > def = {sym = 0x0, dso = 0x7f9eea640b40 <app>}
> > reloc_addr = 0x56104147cf79 <__gmpn_bdiv_q_1+25>
> > sym_val = 0
> > tls_val = 0
> > addend = 131264
> > skip_relative = 0
> > reuse_addends = 0
> > save_slot = 0
> >
> > (gdb) p laddr(dso, rel[0])
> > $27 = (void *) 0x56104147cf79 <__gmpn_bdiv_q_1+25>
> >
> > (gdb) p dso->loadmap
> > $28 = (struct fdpic_loadmap *) 0x0
> >
> > (gdb) p (dso->base + rel[0])
> > $29 = (unsigned char *) 0x56104147cf79 <__gmpn_bdiv_q_1+25> "\300"
> >
> > We can see that "laddr" provided pointer to "dso->base + rel[0]", than
> > switch tried to override it's value and segfault appeared. Pointer is
> > wrong, most likely readonly.
> >
> > You can replace "gcc" with "clang" and everything will be the same.
> Updated
> > binutils to most recent version 2.33.1 and rebuilt toolchain - nothing
> > changed. Pointer is still invalid and SEGV_ACCERR appears.
> >
> > So I think that bug is inside musl itself. Glibc container is the same
> > situation works fine. I see no way to create a workaround for this issue.
>
> musl only has limited support for TEXTRELs as a legacy feature, and
> only on some archs. It does not support them in PIE executables or
> other "new settings".
>
> I think what you're hitting is a somewhat-known issue in libgmp where
> it uses PIC-incompatible code for the .a library but not for the .so.
> There is no good reason for it to do this; the PIC-compatible code is
> just as efficient and should always be used.
>
> I'm not sure if there's a published patch for this issue. One solution
> is using --disable-asm or whatever the option is called to turn off
> the PIC-incompatible asm. But if you want the performance it would be
> preferable to fix it in some other way.
>
> An easy workaround if you don't need PIE is just linking with -no-pie.
>
> Rich
>

[-- Attachment #2: Type: text/html, Size: 7367 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 21:10   ` Szabolcs Nagy
@ 2020-01-29 21:35     ` Андрей Аладьев
  2020-01-29 21:46       ` Rich Felker
  2020-01-29 23:20       ` Szabolcs Nagy
  0 siblings, 2 replies; 26+ messages in thread
From: Андрей Аладьев @ 2020-01-29 21:35 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1839 bytes --]

"readelf -d main | grep TEXTREL" returns the same text on both musl and
glibc containers:

0x0000000000000016 (TEXTREL) 0x0
0x000000000000001e (FLAGS)     TEXTREL

"gcc -no-pie" is another workaround for musl container like Rich said. But
I think that 'set(CMAKE_EXE_LINKER_FLAGS "-static")' will be best cross
platform solution. As I know "-static" implies "no-pie".

> i'm also surprised that it was only a warning, i think gcc default pie
toolchain passes -z text nowadays exactly to make this a link time failure.
this is probably a gentoo toolchain bug.

What do you mean "-z text"? We can report improvement for gentoo.

чт, 30 янв. 2020 г. в 00:10, Szabolcs Nagy <nsz@port70.net>:

> * Rich Felker <dalias@libc.org> [2020-01-29 15:53:30 -0500]:
> > On Wed, Jan 29, 2020 at 09:41:46PM +0300, Андрей Аладьев wrote:
> > > So I think that bug is inside musl itself. Glibc container is the same
> > > situation works fine. I see no way to create a workaround for this
> issue.
> >
> > musl only has limited support for TEXTRELs as a legacy feature, and
> > only on some archs. It does not support them in PIE executables or
> > other "new settings".
>
> i would like to see why this works on glibc.
>
> glibc can process some text relocs but even then
> the elf image will not be shared when multiple
> instances of the same binary are executed
> potentially wasting a lot of ram and icache.
>
> so i don't think the glibc behaviour is desirable.
>
> if the glibc binary does not have textrel (it can
> be checked using readelf -d binary) it would be
> nice to know why.
>
> i'm also surprised that it was only a warning,
> i think gcc default pie toolchain passes -z text
> nowadays exactly to make this a link time failure.
> this is probably a gentoo toolchain bug.
>

[-- Attachment #2: Type: text/html, Size: 2436 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 21:14   ` Андрей Аладьев
@ 2020-01-29 21:43     ` Rich Felker
  0 siblings, 0 replies; 26+ messages in thread
From: Rich Felker @ 2020-01-29 21:43 UTC (permalink / raw)
  To: musl

On Thu, Jan 30, 2020 at 12:14:00AM +0300, Андрей Аладьев wrote:
> Thank you, I will definitely report this issue to gmp or provide more
> information under existing one. Please see here:
> 
> if (dso == &ldso) {
>   /* Only ldso's REL table needs addend saving/reuse. */
>   if (rel == apply_addends_to)
>     reuse_addends = 1;
>   skip_relative = 1;
> }
> 
> if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue;
> 
> Musl already has "skip_relative" flag. This flag can be improved like:
> 
> # ifdef SKIP_RELLOCATION_IN_READONLY_MODE
> if (readonly_mode) {
>   skip_relative = 1;
> }
> # endif
> 
> if (IS_RELATIVE(rel[1], dso->syms)) {
>   if (skip_relative) {
>     continue;
>   } else if (readonly_mode) {
>     error("Error it is not possible to make relocations in readonly mode");
>     a_crash();
>   }
> }
> 
> It will make musl more stronger and user friendlier.

I can't say for sure because this is not a complete patch and probably
not expressing things precisely, but I really don't think this is
doing what you think it's doing. The logic you're trying to modify is
about how the dynamic linker performs multiple passes of relocations
over itself.

Rich

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 21:35     ` Андрей Аладьев
@ 2020-01-29 21:46       ` Rich Felker
  2020-01-29 23:10         ` Андрей Аладьев
  2020-01-29 23:20       ` Szabolcs Nagy
  1 sibling, 1 reply; 26+ messages in thread
From: Rich Felker @ 2020-01-29 21:46 UTC (permalink / raw)
  To: musl

On Thu, Jan 30, 2020 at 12:35:52AM +0300, Андрей Аладьев wrote:
> "readelf -d main | grep TEXTREL" returns the same text on both musl and
> glibc containers:
> 
> 0x0000000000000016 (TEXTREL) 0x0
> 0x000000000000001e (FLAGS)     TEXTREL
> 
> "gcc -no-pie" is another workaround for musl container like Rich said. But
> I think that 'set(CMAKE_EXE_LINKER_FLAGS "-static")' will be best cross
> platform solution. As I know "-static" implies "no-pie".

-static normally does not imply -no-pie with musl target. musl was the
first to introduce static pie, and it was not treated as something
special/weird you have to request, just what you get with -static +
-pie or -static and default-pie toolchain.

When GCC upstreamed static pie with glibc support, they made it so
-static overrides -pie and so you need the new -static-pie to get
static pie. musl patches for gcc revert this change since it's a
regression to the original behavior, treats static-pie a second-class,
and does not work with environments where pie is mandatory (like nommu
targets) where default-pie *must* be honored.

Rich

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 21:46       ` Rich Felker
@ 2020-01-29 23:10         ` Андрей Аладьев
  0 siblings, 0 replies; 26+ messages in thread
From: Андрей Аладьев @ 2020-01-29 23:10 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1824 bytes --]

I've tested and both "-fno-pie" and "-static" are not compatible with some
gcc and clang sanitizers, so these solutions are bad.

Found right solution in gmp source. It was hidden in configure:
"--with-pic" option. I've enabled it and now both glibc and musl works
perfect. Created gentoo bug https://bugs.gentoo.org/707332. For everyone
who will read this thread - you need to enable "--with-pic" option for gmp.
You don't need to disable assembly completely.

So on this week I will try to create small user friendly patch for musl
about readonly relocations.

чт, 30 янв. 2020 г. в 00:46, Rich Felker <dalias@libc.org>:

> On Thu, Jan 30, 2020 at 12:35:52AM +0300, Андрей Аладьев wrote:
> > "readelf -d main | grep TEXTREL" returns the same text on both musl and
> > glibc containers:
> >
> > 0x0000000000000016 (TEXTREL) 0x0
> > 0x000000000000001e (FLAGS)     TEXTREL
> >
> > "gcc -no-pie" is another workaround for musl container like Rich said.
> But
> > I think that 'set(CMAKE_EXE_LINKER_FLAGS "-static")' will be best cross
> > platform solution. As I know "-static" implies "no-pie".
>
> -static normally does not imply -no-pie with musl target. musl was the
> first to introduce static pie, and it was not treated as something
> special/weird you have to request, just what you get with -static +
> -pie or -static and default-pie toolchain.
>
> When GCC upstreamed static pie with glibc support, they made it so
> -static overrides -pie and so you need the new -static-pie to get
> static pie. musl patches for gcc revert this change since it's a
> regression to the original behavior, treats static-pie a second-class,
> and does not work with environments where pie is mandatory (like nommu
> targets) where default-pie *must* be honored.
>
> Rich
>

[-- Attachment #2: Type: text/html, Size: 2370 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 21:35     ` Андрей Аладьев
  2020-01-29 21:46       ` Rich Felker
@ 2020-01-29 23:20       ` Szabolcs Nagy
  1 sibling, 0 replies; 26+ messages in thread
From: Szabolcs Nagy @ 2020-01-29 23:20 UTC (permalink / raw)
  To: musl

* Андрей Аладьев <aladjev.andrew@gmail.com> [2020-01-30 00:35:52 +0300]:
> "readelf -d main | grep TEXTREL" returns the same text on both musl and
> glibc containers:
> 
> 0x0000000000000016 (TEXTREL) 0x0
> 0x000000000000001e (FLAGS)     TEXTREL

ok so the glibc executable is broken too, you just didn't
notice because it's silently wasting resources and will
only fail with pax or selinux hardened setups.

> > i'm also surprised that it was only a warning, i think gcc default pie
> toolchain passes -z text nowadays exactly to make this a link time failure.
> this is probably a gentoo toolchain bug.
> 
> What do you mean "-z text"? We can report improvement for gentoo.

it's an ld flag that makes textrels an error, a toolchain
that defaults to pie should pass it to the linker because
otherwise it's easy to get textrels unintentionally.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-29 20:08   ` Андрей Аладьев
@ 2020-01-30 17:02     ` Markus Wichmann
  2020-01-31  4:24       ` Rich Felker
                         ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Markus Wichmann @ 2020-01-30 17:02 UTC (permalink / raw)
  To: musl

On Wed, Jan 29, 2020 at 11:08:46PM +0300, Андрей Аладьев wrote:
> > Ooh boy, why would you do this? When there's a perfectly good -lgmp just
> waiting for you.
>
> Usage of "/usr/lib/libgmp.a" directly is not forbidden by any toolchain or
> build system. Moreover it is recommended by cmake. You can google for
> "target_link_libraries( site:github.com" and found millions of software
> that uses something like:
>
> find_library(EXTERNAL_LIB)
> target_link_libraries(something ${EXTERNAL_LIB_FOUND})
>

Doesn't that search for the library in the correct mode? I thought cmake
was that smart...

> > The warning is justified, you usually do not want to do this. With a
> TEXTREL, the code has to be mapped as writable, so now programming errors
> and exploits can change the executable code.
>
> This is warning from ld, not from musl. Segfault is not an acceptable
> message from libc. Libc should not try to write into readonly pointer.
>
> > Well, the remedy is obvious: Get rid of the TEXTREL.
>
> Yes, I've found a workaround: "USE='-asm' emerge -v1 gmp", assembly is
> broken, will report it to gmp upstream. But this is not a fix for the issue.
>

There are several ways to achieve this. Getting rid of the assembly is
one such way. In another answer you also advocated for --with-pic. My
solution would probably have been to patch the code to never emit text
relocations in the first place, which is achieved the same way in the
end.

The issue of musl not supporting textrels in the application itself
remains, though.

> > Iterate over the apps PHDRs and remove write protection from all RO
> segments?
>
> So libc knows that file is mapped as readonly and should not try to write
> into readonly pointers.

Almost all relocations point to writable memory. For obvious reasons. So
musl doesn't check this.

The issue is more complicated, because the app can have an unbounded
number of PT_LOAD segments with the PF_W flag absent. So checking the
relocations would require the dynlinker to first iterate over all PHDRs
to check for the unlikely case that textrels are present. Only because
they might be.

> Libc can do the following:
>
> 1. Ignore impossible relocations.
> 2. Add a warning to stderr and still ignore impossible relocations.
> 3. do abort, user will receive SIGABRT and understand that he uses libc in
> a wrong way.
>
> Segfault is not an acceptable answer.
>

Have I got news for you. Unlike glibc, musl does not indicate
irrecoverable state with a litany into stderr, but usually by calling
a_crash(), which will terminate the process by executing an illegal
instruction. This typically results in SIGILL being delivered, but on
some archs it is still a segfault.

Also, there is at least one place in the dynlinker where, as I recall,
mmap() is being called directly, but rather than check for errors in the
return value, the value is just used, because all error returns cause
segfaults.

And then there was the case of PowerPC's original ABI, now called the
BSS-PLT ABI, which expects the dynlinker to fill out the PLT at runtime,
which musl doesn't do. Trying to run a BSS-PLT binary with musl will
therefore also very quickly segfault. musl doesn't fill out the PLT,
because the ABI is old, a replacement has been in place since at least
2003, and PowerPC would be the only arch to need something like this.

Anyway, option 1 would leave the relocations unprocessed, typically
leading to invalid code references down the line, and therefore another
segfault. Option 2 is the same but wordier. Option 3 has a chance to be
subverted (user could block or ignore SIGABRT before executing the main
binary. With SIGSEGV or SIGILL, the user can block or ignore those, but
then the kernel will just kill the process outright if those conditions
arrise).

Options 1 and 2 also have the undesirable effect of possibly only
crashing sometimes, not all the time. See the recent cuserid() thread
about why that is a problem.

And the issue you have with musl, not gmp, still remains: TEXTREL in the
application remains unsupported.

Ciao,
Markus

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-30 17:02     ` Markus Wichmann
@ 2020-01-31  4:24       ` Rich Felker
  2020-01-31 14:47         ` Markus Wichmann
  2020-01-31 15:16       ` Андрей Аладьев
  2020-02-03  3:10       ` Rich Felker
  2 siblings, 1 reply; 26+ messages in thread
From: Rich Felker @ 2020-01-31  4:24 UTC (permalink / raw)
  To: musl

On Thu, Jan 30, 2020 at 06:02:49PM +0100, Markus Wichmann wrote:
> > > Iterate over the apps PHDRs and remove write protection from all RO
> > segments?
> >
> > So libc knows that file is mapped as readonly and should not try to write
> > into readonly pointers.
> 
> Almost all relocations point to writable memory. For obvious reasons. So
> musl doesn't check this.
> 
> The issue is more complicated, because the app can have an unbounded
> number of PT_LOAD segments with the PF_W flag absent. So checking the
> relocations would require the dynlinker to first iterate over all PHDRs
> to check for the unlikely case that textrels are present. Only because
> they might be.

Right. Not specific to textrels, I actually do want to make ldso track
the hull of writable address range for each dso and validate
relocations against it before attempting to apply them. This would
allow error reporting without significant runtime cost (vs iterating
LOAD segments) and would be a first step towards possibly making ldd
of untrusted binaries safe (though that requires a lot more).

> > Libc can do the following:
> >
> > 1. Ignore impossible relocations.
> > 2. Add a warning to stderr and still ignore impossible relocations.
> > 3. do abort, user will receive SIGABRT and understand that he uses libc in
> > a wrong way.
> >
> > Segfault is not an acceptable answer.
> >
> 
> Have I got news for you. Unlike glibc, musl does not indicate
> irrecoverable state with a litany into stderr, but usually by calling
> a_crash(), which will terminate the process by executing an illegal
> instruction. This typically results in SIGILL being delivered, but on
> some archs it is still a segfault.

This is true, but that's after the program has started execution. The
dynamic linker does report errors when it's practical to do so, either
to stderr before execution or via dlerror at runtime. So detecting and
reporting this would not be unprecedented.

> Also, there is at least one place in the dynlinker where, as I recall,
> mmap() is being called directly, but rather than check for errors in the
> return value, the value is just used, because all error returns cause
> segfaults.

I believe this was fixed in 77846800722914eeba170505c2e7f89e12a6beff.

> And then there was the case of PowerPC's original ABI, now called the
> BSS-PLT ABI, which expects the dynlinker to fill out the PLT at runtime,
> which musl doesn't do. Trying to run a BSS-PLT binary with musl will
> therefore also very quickly segfault.

I thought it would produce an error for unsupported relocation type,
but maybe not if the same relocation numbers were reused. This should
probably be improved.

> Anyway, option 1 would leave the relocations unprocessed, typically
> leading to invalid code references down the line, and therefore another
> segfault.

Right. This is really bad and not on the table.

> Option 2 is the same but wordier.

Likewise this makes no sense at all.

> Option 3 has a chance to be
> subverted (user could block or ignore SIGABRT before executing the main
> binary. With SIGSEGV or SIGILL, the user can block or ignore those, but
> then the kernel will just kill the process outright if those conditions
> arrise).

Assuming this is at startup, that's not a possibility; no application
code has run yet. But ldso already has a fatal error mechanism; it
doesn't need to treat this one differently.

For runtime (dlopen), aborting is not an option. Syntactically valid
files which cannot be loaded for semantic reasons should be an error
reported by dlerror. (musl makes no claim to handle syntactically
invalid files safely; doing so is rather difficult and would require
some intense hardening work, and is of little use except for ldd since
otherwise a malicious file could just have malicious code in its
ctors...)

The right action here in the long term is probably reporting
unsupported files rather than crashing. But it's a fairly minor issue
and depends on some infrastructure that's not yet done for tracking
address ranges.

Rich

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-31  4:24       ` Rich Felker
@ 2020-01-31 14:47         ` Markus Wichmann
  2020-01-31 16:35           ` Rich Felker
  0 siblings, 1 reply; 26+ messages in thread
From: Markus Wichmann @ 2020-01-31 14:47 UTC (permalink / raw)
  To: musl

On Thu, Jan 30, 2020 at 11:24:31PM -0500, Rich Felker wrote:
> > Also, there is at least one place in the dynlinker where, as I recall,
> > mmap() is being called directly, but rather than check for errors in the
> > return value, the value is just used, because all error returns cause
> > segfaults.
>
> I believe this was fixed in 77846800722914eeba170505c2e7f89e12a6beff.
>

No, that wasn't what I meant. I looked it up: I meant the one in
static_init_tls(). Note that this was no criticism, I fully agree that
crashing is acceptable in case of a rare failure. As long as it happens
repeatably and only during early startup.

> > And then there was the case of PowerPC's original ABI, now called the
> > BSS-PLT ABI, which expects the dynlinker to fill out the PLT at runtime,
> > which musl doesn't do. Trying to run a BSS-PLT binary with musl will
> > therefore also very quickly segfault.
>
> I thought it would produce an error for unsupported relocation type,
> but maybe not if the same relocation numbers were reused. This should
> probably be improved.
>

Honestly, I went on memory on this. I thought I remembered an FAQ or
wiki entry that said that without secure PLT, you would get crashes. I
never tried it myself.

OK, so the ABI says that the PLT relocations are of type R_PPC_JMP_SLOT.
Which arch/powerpc/reloc.h defines as REL_PLT. Therefore the dynlinker
will see these relocations and perform a generic PLT relocation when the
esoteric BSS-PLT relocation would be called for.

I am using this ABI document here: https://www.polyomino.org.uk/publications/2011/Power-Arch-32-bit-ABI-supp-1.0-Unified.pdf

It appears the type R_PPC_JMP_SLOT did get reused for the secure PLT
option. Therefore our only way to detect BSS-PLT binaries and quit with
a nice error message is to detect the absence of the secure PLT option
in the dynamic section.

Coincidentally, we might give the OP a nice error message as well if we
checked the application's dynamic section and found a DT_TEXTREL tag.

> Assuming this is at startup, that's not a possibility; no application
> code has run yet.

Unfortunately, signal mask and ignore dispositions are inherited across
execve(). A tool that ignores or blocks specific signals before execing
the rest of its command line is therefore possible. I seem to remember
such a tool, but cannot remember its name. A cursory search on the
Internet failed to turn up anything.

Ciao,
Markus

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-30 17:02     ` Markus Wichmann
  2020-01-31  4:24       ` Rich Felker
@ 2020-01-31 15:16       ` Андрей Аладьев
  2020-01-31 16:40         ` Rich Felker
  2020-02-03  3:10       ` Rich Felker
  2 siblings, 1 reply; 26+ messages in thread
From: Андрей Аладьев @ 2020-01-31 15:16 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 5675 bytes --]

Hello Markus, I want to ask a question about this one:

> The issue is more complicated, because the app can have an unbounded
number of PT_LOAD segments with the PF_W flag absent. So checking the
relocations would require the dynlinker to first iterate over all PHDRs to
check for the unlikely case that textrels are present. Only because they
might be.

I made a light code overview and found that there is already a mapping for
segments: "loadmap":

dso->loadmap->segs[i].p_vaddr = ph->p_vaddr;
dso->loadmap->segs[i].p_memsz = ph->p_memsz;

We can add here the following line:
dso->loadmap->segs[i].readonly = ph->p_flags & PF_W;

Than add "readonly" into "fdpic_loadseg":
struct fdpic_loadseg {
  uintptr_t addr, p_vaddr, p_memsz;
  bool readonly;
};

Than we can refactor "do_relocs" function, it will use new function like
"reloc_addr = request_writable_address(dso, rel[0])" instead of "laddr". It
will return "NULL" if address is out of segments or readonly and throw
beautiful error.

But I found that "loadmap" is used only when "DL_FDPIC" is "1". But this is
true only for "sh" arch. Why? This loadmap is very good abstraction the can
live in separate file and be used everywhere.

чт, 30 янв. 2020 г. в 20:03, Markus Wichmann <nullplan@gmx.net>:

> On Wed, Jan 29, 2020 at 11:08:46PM +0300, Андрей Аладьев wrote:
> > > Ooh boy, why would you do this? When there's a perfectly good -lgmp
> just
> > waiting for you.
> >
> > Usage of "/usr/lib/libgmp.a" directly is not forbidden by any toolchain
> or
> > build system. Moreover it is recommended by cmake. You can google for
> > "target_link_libraries( site:github.com" and found millions of software
> > that uses something like:
> >
> > find_library(EXTERNAL_LIB)
> > target_link_libraries(something ${EXTERNAL_LIB_FOUND})
> >
>
> Doesn't that search for the library in the correct mode? I thought cmake
> was that smart...
>
> > > The warning is justified, you usually do not want to do this. With a
> > TEXTREL, the code has to be mapped as writable, so now programming errors
> > and exploits can change the executable code.
> >
> > This is warning from ld, not from musl. Segfault is not an acceptable
> > message from libc. Libc should not try to write into readonly pointer.
> >
> > > Well, the remedy is obvious: Get rid of the TEXTREL.
> >
> > Yes, I've found a workaround: "USE='-asm' emerge -v1 gmp", assembly is
> > broken, will report it to gmp upstream. But this is not a fix for the
> issue.
> >
>
> There are several ways to achieve this. Getting rid of the assembly is
> one such way. In another answer you also advocated for --with-pic. My
> solution would probably have been to patch the code to never emit text
> relocations in the first place, which is achieved the same way in the
> end.
>
> The issue of musl not supporting textrels in the application itself
> remains, though.
>
> > > Iterate over the apps PHDRs and remove write protection from all RO
> > segments?
> >
> > So libc knows that file is mapped as readonly and should not try to write
> > into readonly pointers.
>
> Almost all relocations point to writable memory. For obvious reasons. So
> musl doesn't check this.
>
> The issue is more complicated, because the app can have an unbounded
> number of PT_LOAD segments with the PF_W flag absent. So checking the
> relocations would require the dynlinker to first iterate over all PHDRs
> to check for the unlikely case that textrels are present. Only because
> they might be.
>
> > Libc can do the following:
> >
> > 1. Ignore impossible relocations.
> > 2. Add a warning to stderr and still ignore impossible relocations.
> > 3. do abort, user will receive SIGABRT and understand that he uses libc
> in
> > a wrong way.
> >
> > Segfault is not an acceptable answer.
> >
>
> Have I got news for you. Unlike glibc, musl does not indicate
> irrecoverable state with a litany into stderr, but usually by calling
> a_crash(), which will terminate the process by executing an illegal
> instruction. This typically results in SIGILL being delivered, but on
> some archs it is still a segfault.
>
> Also, there is at least one place in the dynlinker where, as I recall,
> mmap() is being called directly, but rather than check for errors in the
> return value, the value is just used, because all error returns cause
> segfaults.
>
> And then there was the case of PowerPC's original ABI, now called the
> BSS-PLT ABI, which expects the dynlinker to fill out the PLT at runtime,
> which musl doesn't do. Trying to run a BSS-PLT binary with musl will
> therefore also very quickly segfault. musl doesn't fill out the PLT,
> because the ABI is old, a replacement has been in place since at least
> 2003, and PowerPC would be the only arch to need something like this.
>
> Anyway, option 1 would leave the relocations unprocessed, typically
> leading to invalid code references down the line, and therefore another
> segfault. Option 2 is the same but wordier. Option 3 has a chance to be
> subverted (user could block or ignore SIGABRT before executing the main
> binary. With SIGSEGV or SIGILL, the user can block or ignore those, but
> then the kernel will just kill the process outright if those conditions
> arrise).
>
> Options 1 and 2 also have the undesirable effect of possibly only
> crashing sometimes, not all the time. See the recent cuserid() thread
> about why that is a problem.
>
> And the issue you have with musl, not gmp, still remains: TEXTREL in the
> application remains unsupported.
>
> Ciao,
> Markus
>

[-- Attachment #2: Type: text/html, Size: 6741 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-31 14:47         ` Markus Wichmann
@ 2020-01-31 16:35           ` Rich Felker
  0 siblings, 0 replies; 26+ messages in thread
From: Rich Felker @ 2020-01-31 16:35 UTC (permalink / raw)
  To: musl

On Fri, Jan 31, 2020 at 03:47:48PM +0100, Markus Wichmann wrote:
> > Assuming this is at startup, that's not a possibility; no application
> > code has run yet.
> 
> Unfortunately, signal mask and ignore dispositions are inherited across
> execve(). A tool that ignores or blocks specific signals before execing
> the rest of its command line is therefore possible. I seem to remember
> such a tool, but cannot remember its name. A cursory search on the
> Internet failed to turn up anything.

For synchronously-generated SIGSEGV or SIGILL from faults, all that
ignoring or blocking them does is ensure that a handler can't run and
that they terminate the process (this is implementation-specific but a
Linux contract and The Right Thing to do). Signal handlers of course
cannot be inherited across exec; they revert to SIG_DFL.

Rich

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-31 15:16       ` Андрей Аладьев
@ 2020-01-31 16:40         ` Rich Felker
  2020-01-31 17:51           ` Андрей Аладьев
  0 siblings, 1 reply; 26+ messages in thread
From: Rich Felker @ 2020-01-31 16:40 UTC (permalink / raw)
  To: musl

On Fri, Jan 31, 2020 at 06:16:19PM +0300, Андрей Аладьев wrote:
> Hello Markus, I want to ask a question about this one:
> 
> > The issue is more complicated, because the app can have an unbounded
> number of PT_LOAD segments with the PF_W flag absent. So checking the
> relocations would require the dynlinker to first iterate over all PHDRs to
> check for the unlikely case that textrels are present. Only because they
> might be.
> 
> I made a light code overview and found that there is already a mapping for
> segments: "loadmap":
> 
> dso->loadmap->segs[i].p_vaddr = ph->p_vaddr;
> dso->loadmap->segs[i].p_memsz = ph->p_memsz;

This is only for FDPIC, which is not used on any platforms you care
about unless you already know what it is. :-)

> We can add here the following line:
> dso->loadmap->segs[i].readonly = ph->p_flags & PF_W;
> 
> Than add "readonly" into "fdpic_loadseg":
> struct fdpic_loadseg {
>   uintptr_t addr, p_vaddr, p_memsz;
>   bool readonly;
> };

No you can't, because this structure is ABI between the loader (kernel
or otherwise) and the program. It's not an internal structure of the
dynamic linker.

Moreover, adding such a thing is not desirable because it adds a
linear-search of an array of load segments to each relocation,
increasing load time of every correct program for the sake of
diagnosing incorrect ones in a friendly manner. This is not a
reasonable tradeoff and it's why I proposed the "hull" approach
(that's O(1) and safe against bogus relocations clobbering memory
outside the range of the library being relocated, but could still
fault with a mix of LOAD maps). The FDPIC approach is only done
because it's essential for being able to share program text on a
system without MMU, not because it's "nice".

Rich

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-31 16:40         ` Rich Felker
@ 2020-01-31 17:51           ` Андрей Аладьев
  2020-01-31 18:01             ` Rich Felker
  0 siblings, 1 reply; 26+ messages in thread
From: Андрей Аладьев @ 2020-01-31 17:51 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 2829 bytes --]

> Moreover, adding such a thing is not desirable because it adds a
linear-search of an array of load segments to each relocation

I think it is possible to make this search O(log n).

for (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz;
j++);

This code takes first segment that can handle address. It looks possible to
create modified list of virtual segments, that won't overlap and make a
binary search.

> This is not a reasonable tradeoff and it's why I proposed the "hull"
approach

It may not be safe from maintainability perspective. Library will be
changed, everybody will forget what part of code was protected by external
validation and it will provide unexpected behaviour. Please consider double
validation approach: external validation in production and debug only mode
with loadmap like validation.

пт, 31 янв. 2020 г. в 19:40, Rich Felker <dalias@libc.org>:

> On Fri, Jan 31, 2020 at 06:16:19PM +0300, Андрей Аладьев wrote:
> > Hello Markus, I want to ask a question about this one:
> >
> > > The issue is more complicated, because the app can have an unbounded
> > number of PT_LOAD segments with the PF_W flag absent. So checking the
> > relocations would require the dynlinker to first iterate over all PHDRs
> to
> > check for the unlikely case that textrels are present. Only because they
> > might be.
> >
> > I made a light code overview and found that there is already a mapping
> for
> > segments: "loadmap":
> >
> > dso->loadmap->segs[i].p_vaddr = ph->p_vaddr;
> > dso->loadmap->segs[i].p_memsz = ph->p_memsz;
>
> This is only for FDPIC, which is not used on any platforms you care
> about unless you already know what it is. :-)
>
> > We can add here the following line:
> > dso->loadmap->segs[i].readonly = ph->p_flags & PF_W;
> >
> > Than add "readonly" into "fdpic_loadseg":
> > struct fdpic_loadseg {
> >   uintptr_t addr, p_vaddr, p_memsz;
> >   bool readonly;
> > };
>
> No you can't, because this structure is ABI between the loader (kernel
> or otherwise) and the program. It's not an internal structure of the
> dynamic linker.
>
> Moreover, adding such a thing is not desirable because it adds a
> linear-search of an array of load segments to each relocation,
> increasing load time of every correct program for the sake of
> diagnosing incorrect ones in a friendly manner. This is not a
> reasonable tradeoff and it's why I proposed the "hull" approach
> (that's O(1) and safe against bogus relocations clobbering memory
> outside the range of the library being relocated, but could still
> fault with a mix of LOAD maps). The FDPIC approach is only done
> because it's essential for being able to share program text on a
> system without MMU, not because it's "nice".
>
> Rich
>

[-- Attachment #2: Type: text/html, Size: 3510 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-31 17:51           ` Андрей Аладьев
@ 2020-01-31 18:01             ` Rich Felker
  2020-01-31 19:11               ` Андрей Аладьев
  0 siblings, 1 reply; 26+ messages in thread
From: Rich Felker @ 2020-01-31 18:01 UTC (permalink / raw)
  To: musl

On Fri, Jan 31, 2020 at 08:51:05PM +0300, Андрей Аладьев wrote:
> > Moreover, adding such a thing is not desirable because it adds a
> linear-search of an array of load segments to each relocation
> 
> I think it is possible to make this search O(log n).

This would help if n were large, but in practice it's very small (2-3
or maybe 4) and the cost is just the code path overhead, which gets
worse if you do that, not the largeness of n.

> for (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz;
> j++);
> 
> This code takes first segment that can handle address. It looks possible to
> create modified list of virtual segments, that won't overlap and make a
> binary search.

They're non-overlapping anyway but not necessarily sorted, and can't
be simultaneously sorted by addr and p_vaddr since the orders will
differ.

> > This is not a reasonable tradeoff and it's why I proposed the "hull"
> approach
> 
> It may not be safe from maintainability perspective. Library will be
> changed, everybody will forget what part of code was protected by external
> validation and it will provide unexpected behaviour. Please consider double
> validation approach: 

You're really not making sense here. What does "protected by external
validation" mean? There is presently nothing being "protected" here;
the discussion is just about more informative errors. If this is used
as a boundary for some sort of safety at some point in the future (as
mentioned before, the benefit of this is probably limited to ldd and
thus not very useful) then it will be done according to constraints
needed to achieve that.

> external validation in production and debug only mode
> with loadmap like validation.

We do not have separate "production" and "debug" modes. This kind of
thing (combinatoric build-time options) is what lacks maintainability.

Rich

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-31 18:01             ` Rich Felker
@ 2020-01-31 19:11               ` Андрей Аладьев
  0 siblings, 0 replies; 26+ messages in thread
From: Андрей Аладьев @ 2020-01-31 19:11 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 2132 bytes --]

Now everything is clear, thank you. Have a good weekend =)

пт, 31 янв. 2020 г. в 21:01, Rich Felker <dalias@libc.org>:

> On Fri, Jan 31, 2020 at 08:51:05PM +0300, Андрей Аладьев wrote:
> > > Moreover, adding such a thing is not desirable because it adds a
> > linear-search of an array of load segments to each relocation
> >
> > I think it is possible to make this search O(log n).
>
> This would help if n were large, but in practice it's very small (2-3
> or maybe 4) and the cost is just the code path overhead, which gets
> worse if you do that, not the largeness of n.
>
> > for (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz;
> > j++);
> >
> > This code takes first segment that can handle address. It looks possible
> to
> > create modified list of virtual segments, that won't overlap and make a
> > binary search.
>
> They're non-overlapping anyway but not necessarily sorted, and can't
> be simultaneously sorted by addr and p_vaddr since the orders will
> differ.
>
> > > This is not a reasonable tradeoff and it's why I proposed the "hull"
> > approach
> >
> > It may not be safe from maintainability perspective. Library will be
> > changed, everybody will forget what part of code was protected by
> external
> > validation and it will provide unexpected behaviour. Please consider
> double
> > validation approach:
>
> You're really not making sense here. What does "protected by external
> validation" mean? There is presently nothing being "protected" here;
> the discussion is just about more informative errors. If this is used
> as a boundary for some sort of safety at some point in the future (as
> mentioned before, the benefit of this is probably limited to ldd and
> thus not very useful) then it will be done according to constraints
> needed to achieve that.
>
> > external validation in production and debug only mode
> > with loadmap like validation.
>
> We do not have separate "production" and "debug" modes. This kind of
> thing (combinatoric build-time options) is what lacks maintainability.
>
> Rich
>

[-- Attachment #2: Type: text/html, Size: 2644 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-01-30 17:02     ` Markus Wichmann
  2020-01-31  4:24       ` Rich Felker
  2020-01-31 15:16       ` Андрей Аладьев
@ 2020-02-03  3:10       ` Rich Felker
  2020-02-03  4:05         ` Rich Felker
  2020-02-03  4:32         ` Markus Wichmann
  2 siblings, 2 replies; 26+ messages in thread
From: Rich Felker @ 2020-02-03  3:10 UTC (permalink / raw)
  To: musl

On Thu, Jan 30, 2020 at 06:02:49PM +0100, Markus Wichmann wrote:
> > > The warning is justified, you usually do not want to do this. With a
> > TEXTREL, the code has to be mapped as writable, so now programming errors
> > and exploits can change the executable code.
> >
> > This is warning from ld, not from musl. Segfault is not an acceptable
> > message from libc. Libc should not try to write into readonly pointer.
> >
> > > Well, the remedy is obvious: Get rid of the TEXTREL.
> >
> > Yes, I've found a workaround: "USE='-asm' emerge -v1 gmp", assembly is
> > broken, will report it to gmp upstream. But this is not a fix for the issue.
> >
> 
> There are several ways to achieve this. Getting rid of the assembly is
> one such way. In another answer you also advocated for --with-pic. My
> solution would probably have been to patch the code to never emit text
> relocations in the first place, which is achieved the same way in the
> end.

Users have hit this issue in musl-cross-make when the compiler being
used to compile the toolchain is default-pie and system-wide gmp is
not being used, except that it's a link error (as it should be) which
mpfr's configure script hits when testing linking against libgmp,
rather than runtime crash.

I'll probably end up having mcm pass --with-pic to GCC's top-level
configure, but I see this will be picked up by some other libs like
libcc1, which oddly aren't failing for the same reason. Any idea why?
Is this the right fix for mcm? What could/should be done to unbreak
gmp with default-pie toolchains? Is it a bug in the version of libtool
they're using or a bug in gmp?

Rich

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-02-03  3:10       ` Rich Felker
@ 2020-02-03  4:05         ` Rich Felker
  2020-02-03  4:32         ` Markus Wichmann
  1 sibling, 0 replies; 26+ messages in thread
From: Rich Felker @ 2020-02-03  4:05 UTC (permalink / raw)
  To: musl

On Sun, Feb 02, 2020 at 10:10:36PM -0500, Rich Felker wrote:
> On Thu, Jan 30, 2020 at 06:02:49PM +0100, Markus Wichmann wrote:
> > > > The warning is justified, you usually do not want to do this. With a
> > > TEXTREL, the code has to be mapped as writable, so now programming errors
> > > and exploits can change the executable code.
> > >
> > > This is warning from ld, not from musl. Segfault is not an acceptable
> > > message from libc. Libc should not try to write into readonly pointer.
> > >
> > > > Well, the remedy is obvious: Get rid of the TEXTREL.
> > >
> > > Yes, I've found a workaround: "USE='-asm' emerge -v1 gmp", assembly is
> > > broken, will report it to gmp upstream. But this is not a fix for the issue.
> > >
> > 
> > There are several ways to achieve this. Getting rid of the assembly is
> > one such way. In another answer you also advocated for --with-pic. My
> > solution would probably have been to patch the code to never emit text
> > relocations in the first place, which is achieved the same way in the
> > end.
> 
> Users have hit this issue in musl-cross-make when the compiler being
> used to compile the toolchain is default-pie and system-wide gmp is
> not being used, except that it's a link error (as it should be) which
> mpfr's configure script hits when testing linking against libgmp,
> rather than runtime crash.
> 
> I'll probably end up having mcm pass --with-pic to GCC's top-level
> configure, but I see this will be picked up by some other libs like
> libcc1, which oddly aren't failing for the same reason. Any idea why?
> Is this the right fix for mcm? What could/should be done to unbreak
> gmp with default-pie toolchains? Is it a bug in the version of libtool
> they're using or a bug in gmp?

OK, --with-pic fixes it, but not for users using slibtool in place of
the shipped libtool since gmp is pulling the flag out of libtool
internals somehow and usint that to decide how to generate its
preprocessed asm sources. Eew.

Do you (or anyone else) know a way to force gmp's asm preprocessor to
always pick the PIC version of the asm, without poking at libtool
internals? I'd like to fix this with gmp patches we could ship in mcm,
but if there's no easy solution immediately found I'll probably just
add --disable-assembly for now.

Rich

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-02-03  3:10       ` Rich Felker
  2020-02-03  4:05         ` Rich Felker
@ 2020-02-03  4:32         ` Markus Wichmann
  2020-02-03  4:40           ` Rich Felker
  1 sibling, 1 reply; 26+ messages in thread
From: Markus Wichmann @ 2020-02-03  4:32 UTC (permalink / raw)
  To: musl

On Sun, Feb 02, 2020 at 10:10:36PM -0500, Rich Felker wrote:
> I'll probably end up having mcm pass --with-pic to GCC's top-level
> configure, but I see this will be picked up by some other libs like
> libcc1, which oddly aren't failing for the same reason. Any idea why?

I'd guess they don't use assembly, or at least their assembly does not
try to access global symbols. I haven't looked at the source though. And
I won't until the afternoon at least.

> Is this the right fix for mcm? What could/should be done to unbreak
> gmp with default-pie toolchains? Is it a bug in the version of libtool
> they're using or a bug in gmp?
>
> Rich

The problem is with the assumptions of GMP. And I really don't know how
to fix those. GMP's build system generates a dynamic and a static
library, and assumes that the static library does not need to be PIC.
With the advent of static-pie, this assumption is subverted. But how to
deal with this generally? Many libraries assume the static one does not
need PIC. And while PIC has little to no overhead on AMD64, other
architectures are not so forgiving. For example, on PowerPC, you need to
set up a GOT pointer first, which requires spilling the link register,
calling the next instruction so you can get its address, adding the
offset to the GOT to that, then adding the GOT relocation to that. So
you get the non-PIC code:

    lis rX,sym@ha
    addi rX,rX,sym@l

turning into the PIC code:

    mflr r0
    bcl 20,31,1f
1:  mflr rX
    addis rX,rX,(_GLOBAL_OFFSET_TABLE_ - 1b)@ha
    addi rX,rX,(_GLOBAL_OFFSET_TABLE_ - 1b)@l
    mtlr r0
    lwz rX,sym@got(rX)

(Wait, can sym@got exceed 32k? Then that last instruction turns into two
instructions again.)

It would be hard to argue that the latter is as efficient as the former,
is my point.

In case of GMP, I would argue they can add a test to determine if the
toolchain generates static-pie, and turn on PIC by default if so. No
clue if upstream will like that, though.

Ciao,
Markus

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [musl] Static linking is broken after creation of DT_TEXTREL segment
  2020-02-03  4:32         ` Markus Wichmann
@ 2020-02-03  4:40           ` Rich Felker
  0 siblings, 0 replies; 26+ messages in thread
From: Rich Felker @ 2020-02-03  4:40 UTC (permalink / raw)
  To: musl

On Mon, Feb 03, 2020 at 05:32:51AM +0100, Markus Wichmann wrote:
> On Sun, Feb 02, 2020 at 10:10:36PM -0500, Rich Felker wrote:
> > I'll probably end up having mcm pass --with-pic to GCC's top-level
> > configure, but I see this will be picked up by some other libs like
> > libcc1, which oddly aren't failing for the same reason. Any idea why?
> 
> I'd guess they don't use assembly, or at least their assembly does not
> try to access global symbols. I haven't looked at the source though. And
> I won't until the afternoon at least.
> 
> > Is this the right fix for mcm? What could/should be done to unbreak
> > gmp with default-pie toolchains? Is it a bug in the version of libtool
> > they're using or a bug in gmp?
> >
> > Rich
> 
> The problem is with the assumptions of GMP. And I really don't know how
> to fix those. GMP's build system generates a dynamic and a static
> library, and assumes that the static library does not need to be PIC.
> With the advent of static-pie, this assumption is subverted. But how to

Even before static-pie it was wrong. If you're making a dynamic-linked
PIE executable but want to static link libgmp, it will be wrong.

> deal with this generally? Many libraries assume the static one does not
> need PIC.

Everything else honors the compiler's default. If $(CC) was built for
default-pie, or if you set CC="gcc -fPIE -pie" or something similar,
you'd get a static library that's PIE-compatible. Only gmp is broken
because its asm is wrongly poking at some libtool vars rather than
__PIC__ from the compiler.

> In case of GMP, I would argue they can add a test to determine if the
> toolchain generates static-pie, and turn on PIC by default if so. No
> clue if upstream will like that, though.

All they need to do is look at __PIC__ in place of whatever wrong test
they're doing now. The question is just how easy this is to patch.

Rich

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2020-02-03  4:40 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-29 18:41 [musl] Static linking is broken after creation of DT_TEXTREL segment Андрей Аладьев
2020-01-29 19:19 ` Markus Wichmann
2020-01-29 19:38   ` Markus Wichmann
2020-01-29 20:48     ` Rich Felker
2020-01-29 20:08   ` Андрей Аладьев
2020-01-30 17:02     ` Markus Wichmann
2020-01-31  4:24       ` Rich Felker
2020-01-31 14:47         ` Markus Wichmann
2020-01-31 16:35           ` Rich Felker
2020-01-31 15:16       ` Андрей Аладьев
2020-01-31 16:40         ` Rich Felker
2020-01-31 17:51           ` Андрей Аладьев
2020-01-31 18:01             ` Rich Felker
2020-01-31 19:11               ` Андрей Аладьев
2020-02-03  3:10       ` Rich Felker
2020-02-03  4:05         ` Rich Felker
2020-02-03  4:32         ` Markus Wichmann
2020-02-03  4:40           ` Rich Felker
2020-01-29 20:53 ` Rich Felker
2020-01-29 21:10   ` Szabolcs Nagy
2020-01-29 21:35     ` Андрей Аладьев
2020-01-29 21:46       ` Rich Felker
2020-01-29 23:10         ` Андрей Аладьев
2020-01-29 23:20       ` Szabolcs Nagy
2020-01-29 21:14   ` Андрей Аладьев
2020-01-29 21:43     ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).