I noticed same error seemed to have occurred from user installing to gentoo Linux. I can't tell from this if it was resolved or not (I'm relatively inexperienced)
https://bugs.gentoo.org/713178
One thing in common between Alpine and this environment is they are using musl libc
Could that be an issue?
On Sat, Oct 17, 2020, at 6:29 PM, David Topham wrote:
I noticed same error seemed to have occurred from user installing to gentoo Linux. I can't tell from this if it was resolved or not (I'm relatively inexperienced)
https://bugs.gentoo.org/713178
One thing in common between Alpine and this environment is they are using musl libc
Could that be an issue?
I built polyml HEAD in an alpine chroot and reproduced the crash.
e6081b5540fb:~/polyml$ readelf -d .libs/lt-poly | grep TEXTREL 0x0000000000000016 (TEXTREL) 0x0
TEXTREL is not supported by musl, so this is the problem. This indicates that position-dependent code has somehow gotten into an executable marked as PIE.
If I configure poly/ml using:
./configure LDFLAGS="-no-pie"
it works.
Nothing is installed here except musl-dev gcc g++ make git curl; it is a fresh git checkout, rev d68c673.
Looking at polyexport.o (with objdump -d -r) there are a large number of X86_64_RELATIVE relocations in area%1u symbols, mixed with data that visually looks like x86_64 machine code. The relocations apply to aligned 64-bit blocks, not 64-bit immediates in move instructions. Not sure if this is easily fixable or if poly does something like old GHC that relies on mixing data and code so closely.
-s
Hi, I'm pleased you've found a fix for this. A while ago I looked into how to get Poly/ML to install on hardened systems such as SELinux and OpenBSD and fixed a problem with dynamically created code which generally requires an area of memory to be both executable and writeable. Textrels were still a problem and required a linker option. See http://lists.inf.ed.ac.uk/pipermail/polyml/2020-August/002370.html .
As I understand it, a TEXTREL is where the TEXT, executable, read-only code contains an absolute address. When Poly/ML compiles a function the code object it creates consists of the machine code followed by a section of constants, often addresses. Even if the function itself does not use an address there is always a pointer to the name of the function as a string and to a ref that can be used for profiling. I would guess that it is these that result in the TEXTRELs.
I would assume that it is still possible to have absolute addresses in an executable but that these are supposed to be in a data section rather than in the text section. Is that the case? It is certainly not possible to create an ML object file without any absolute addresses since the object file could contain structures such as lists. If the section of constants for a function were pulled out so that they were written into a data section would that solve the problem? Currently, at least on the X86-64, the code itself uses PC-relative addressing to access the constant area. The offsets are currently frozen when the code is built since the constant area does not move relative to code but that would change if the constants were part of a different object file section.
Regards, David
On 18/10/2020 00:25, Stefan O'Rear wrote:
On Sat, Oct 17, 2020, at 6:29 PM, David Topham wrote:
I noticed same error seemed to have occurred from user installing to gentoo Linux. I can't tell from this if it was resolved or not (I'm relatively inexperienced)
https://bugs.gentoo.org/713178
One thing in common between Alpine and this environment is they are using musl libc
Could that be an issue?
I built polyml HEAD in an alpine chroot and reproduced the crash.
e6081b5540fb:~/polyml$ readelf -d .libs/lt-poly | grep TEXTREL 0x0000000000000016 (TEXTREL) 0x0
TEXTREL is not supported by musl, so this is the problem. This indicates that position-dependent code has somehow gotten into an executable marked as PIE.
If I configure poly/ml using:
./configure LDFLAGS="-no-pie"
it works.
Nothing is installed here except musl-dev gcc g++ make git curl; it is a fresh git checkout, rev d68c673.
Looking at polyexport.o (with objdump -d -r) there are a large number of X86_64_RELATIVE relocations in area%1u symbols, mixed with data that visually looks like x86_64 machine code. The relocations apply to aligned 64-bit blocks, not 64-bit immediates in move instructions. Not sure if this is easily fixable or if poly does something like old GHC that relies on mixing data and code so closely.
-s _______________________________________________ polyml mailing list polyml at inf.ed.ac.uk http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
On Mon, Oct 19, 2020, at 3:15 AM, David Matthews wrote:
Hi, I'm pleased you've found a fix for this. A while ago I looked into how to get Poly/ML to install on hardened systems such as SELinux and OpenBSD and fixed a problem with dynamically created code which generally requires an area of memory to be both executable and writeable. Textrels were still a problem and required a linker option. See http://lists.inf.ed.ac.uk/pipermail/polyml/2020-August/002370.html .
As I understand it, a TEXTREL is where the TEXT, executable, read-only code contains an absolute address. When Poly/ML compiles a function the
AFAIK, strictly speaking, executability is not relevant here. The Linux manpage documents DT_TEXTREL as "Absence of this entry indicates that no relocation entries should apply to a nonwritable segment" and musl is crashing because it maps the text segment with r-x permissions, and then attempts to write to it while processing relocations.
A related issue is that musl only implements the relocation types that are useful in data sections, i.e. "write absolute address to a word-sized adequately aligned field".
code object it creates consists of the machine code followed by a section of constants, often addresses. Even if the function itself does not use an address there is always a pointer to the name of the function as a string and to a ref that can be used for profiling. I would guess that it is these that result in the TEXTRELs.
I would assume that it is still possible to have absolute addresses in an executable but that these are supposed to be in a data section rather than in the text section. Is that the case? It is certainly not
Yes, in C you can initialize a global variable with a pointer to another global variable.
possible to create an ML object file without any absolute addresses since the object file could contain structures such as lists. If the section of constants for a function were pulled out so that they were written into a data section would that solve the problem? Currently, at least on the X86-64, the code itself uses PC-relative addressing to access the constant area. The offsets are currently frozen when the code is built since the constant area does not move relative to code but that would change if the constants were part of a different object file section.
I think you should still be able to use PC-relative addressing there, as long as the relocations can be completely resolved at the initial link time.
Supporting PIE on 32-bit x86 would be harder. Would it be reasonable to have a configure test which automatically sets -no-pie if the linker supports it, and/or if a test program with a text relocation cannot be run?
Regards, David
On 18/10/2020 00:25, Stefan O'Rear wrote:
On Sat, Oct 17, 2020, at 6:29 PM, David Topham wrote:
I noticed same error seemed to have occurred from user installing to gentoo Linux. I can't tell from this if it was resolved or not (I'm relatively inexperienced)
https://bugs.gentoo.org/713178
One thing in common between Alpine and this environment is they are using musl libc
Could that be an issue?
I built polyml HEAD in an alpine chroot and reproduced the crash.
e6081b5540fb:~/polyml$ readelf -d .libs/lt-poly | grep TEXTREL 0x0000000000000016 (TEXTREL) 0x0
TEXTREL is not supported by musl, so this is the problem. This indicates that position-dependent code has somehow gotten into an executable marked as PIE.
If I configure poly/ml using:
./configure LDFLAGS="-no-pie"
it works.
Nothing is installed here except musl-dev gcc g++ make git curl; it is a fresh git checkout, rev d68c673.
Looking at polyexport.o (with objdump -d -r) there are a large number of X86_64_RELATIVE relocations in area%1u symbols, mixed with data that visually looks like x86_64 machine code. The relocations apply to aligned 64-bit blocks, not 64-bit immediates in move instructions. Not sure if this is easily fixable or if poly does something like old GHC that relies on mixing data and code so closely.
-s _______________________________________________ polyml mailing list polyml at inf.ed.ac.uk http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
polyml mailing list polyml at inf.ed.ac.uk http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
On 19/10/2020 09:19, Stefan O'Rear wrote:
AFAIK, strictly speaking, executability is not relevant here. The Linux manpage documents DT_TEXTREL as "Absence of this entry indicates that no relocation entries should apply to a nonwritable segment" and musl is crashing because it maps the text segment with r-x permissions, and then attempts to write to it while processing relocations.
A related issue is that musl only implements the relocation types that are useful in data sections, i.e. "write absolute address to a word-sized adequately aligned field".
I think you're right about the issue being relocations in any read-only section, not just the code as I'd imagined.
I've been doing some tests with the byte-code interpreted version. Currently the interpreted code is put in the text section but there's no need for that; it really should be put in the read-only data area along with all the other immutable data. However, even then the linker on OpenBSD complains about relocations in the read-only data area and I am guessing that this has to do as much with the rest of the data as with the byte code. Writing everything to a read-write area solves the problem.
This seems bizarre. What it means is that it is actually necessary weaken security by making immutable data writeable in order to allow absolute addresses. I would have expected the loader to deal with the relocations in the read-only data area and then remove write access from the pages. Is there any way round this?
Supporting PIE on 32-bit x86 would be harder. Would it be reasonable to have a configure test which automatically sets -no-pie if the linker supports it, and/or if a test program with a text relocation cannot be run?
That would certainly be a good idea.
Regards, David
On 19 Oct 2020, at 18:05, David Matthews <David.Matthews at prolingua.co.uk> wrote:
On 19/10/2020 09:19, Stefan O'Rear wrote:
AFAIK, strictly speaking, executability is not relevant here. The Linux manpage documents DT_TEXTREL as "Absence of this entry indicates that no relocation entries should apply to a nonwritable segment" and musl is crashing because it maps the text segment with r-x permissions, and then attempts to write to it while processing relocations. A related issue is that musl only implements the relocation types that are useful in data sections, i.e. "write absolute address to a word-sized adequately aligned field".
I think you're right about the issue being relocations in any read-only section, not just the code as I'd imagined.
I've been doing some tests with the byte-code interpreted version. Currently the interpreted code is put in the text section but there's no need for that; it really should be put in the read-only data area along with all the other immutable data. However, even then the linker on OpenBSD complains about relocations in the read-only data area and I am guessing that this has to do as much with the rest of the data as with the byte code. Writing everything to a read-write area solves the problem.
This seems bizarre. What it means is that it is actually necessary weaken security by making immutable data writeable in order to allow absolute addresses. I would have expected the loader to deal with the relocations in the read-only data area and then remove write access from the pages. Is there any way round this?
Yes, using .data.rel.ro., i.e. relocatable read-only data.
Jess
On 19/10/2020 18:12, Jessica Clarke wrote:
This seems bizarre. What it means is that it is actually necessary weaken security by making immutable data writeable in order to allow absolute addresses. I would have expected the loader to deal with the relocations in the read-only data area and then remove write access from the pages. Is there any way round this?
Yes, using .data.rel.ro., i.e. relocatable read-only data.
Thanks, Jess. That seems to work, at least on SELinux and Alpine. OpenBSD seems to still want it to be writeable.
David
On 19/10/2020 21:08, David Matthews wrote:
Yes, using .data.rel.ro., i.e. relocatable read-only data.
Thanks, Jess.? That seems to work, at least on SELinux and Alpine. OpenBSD seems to still want it to be writeable.
I've now changed the ELF exporter to write the data to .data.rel.ro. The byte code interpreted version (--disable-native-codegeneration) now builds without a problem on Alpine Linux and on SELinux with hardening turned on. That isn't a complete solution because it doesn't deal with native code but it does show that if code could be handled everything else will work.
I see this primarily as future-proofing Poly/ML. It's not unlikely that a future release of, say Mac OS X, might outlaw TEXTRELs.
David