Bug 29448

Summary: aarch64: "has a LOAD segment with RWX permissions"
Product: binutils Reporter: Jérôme Forissier <jerome.forissier>
Component: ldAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED NOTABUG    
Severity: normal CC: nickc, pinskia, rfhn.fhbrrjnzeneqpf
Priority: P2    
Version: 2.39   
Target Milestone: ---   
See Also: https://github.com/OP-TEE/optee_os/issues/5471#issuecomment-1205362895
Host: Target:
Build: Last reconfirmed:

Description Jérôme Forissier 2022-08-04 15:57:20 UTC
ld.bfd is producing the following warning:

aarch64-linux-gnu-ld.bfd: warning: out/arm-plat-vexpress/core/tee.elf has a LOAD segment with RWX permissions

tee.elf is produced with a custom linker script. Full details on how to reproduce may be found at https://github.com/OP-TEE/optee_os/issues/5471#issuecomment-1205362895, but in a nutshell this seems related to #21252.

Previously, no warning was output. Now that the linker warns by default, it causes build errors with --fatal-warnings (obviously) which is a bit annoying.
Comment 1 Nick Clifton 2022-08-05 09:42:38 UTC
(In reply to Jérôme Forissier from comment #0)
 
> tee.elf is produced with a custom linker script.

Do you *want* a segment with read, write and execute permission ?  It does represent a potential security vulnerability and it might be worth your time to examine the linker script and see if you can put the code and the data into separate segments.


> Previously, no warning was output. Now that the linker warns by default, it
> causes build errors with --fatal-warnings (obviously) which is a bit
> annoying.

Assuming that you want to keep things the way that they are you can use the --no-warn-rwx-segments command line option to disable the message.

Cheers
  Nick
Comment 2 Jérôme Forissier 2022-08-05 09:59:58 UTC
(In reply to Nick Clifton from comment #1)
> (In reply to Jérôme Forissier from comment #0)
>  
> > tee.elf is produced with a custom linker script.
> 
> Do you *want* a segment with read, write and execute permission ?

Currently it doesn't matter because the ELF segment information is not used to define MMU permissions. It is a special situation, the ELF is an OS kernel, it is further processed to extract all LOAD segments and produce a raw binary. The runtime MMU mappings are defined based on delimiters (symbols) in the binary.

>  It does
> represent a potential security vulnerability and it might be worth your time
> to examine the linker script and see if you can put the code and the data
> into separate segments.

Yes I understand that, what I am questioning is why ld doesn't emit several LOAD segments it on its own (like Clang does for instance, with the same linker script) since I give it no constraint whatsoever. The linker script has no PHDRS instructing to merge .text .rodata .data, yet they all end up in the same segment.
  
> > Previously, no warning was output. Now that the linker warns by default, it
> > causes build errors with --fatal-warnings (obviously) which is a bit
> > annoying.
> 
> Assuming that you want to keep things the way that they are you can use the
> --no-warn-rwx-segments command line option to disable the message.

Yep that's a reasonable thing to do in my case, but still, I think the behavior is a bit weird. Again, ld deciding to create that RWX segment and later complaining about its own decision ;-)

Thanks.
-- 
Jerome
Comment 3 Nick Clifton 2022-08-05 15:54:10 UTC
(In reply to Jérôme Forissier from comment #2)
  
> Yep that's a reasonable thing to do in my case, but still, I think the
> behavior is a bit weird. Again, ld deciding to create that RWX segment and
> later complaining about its own decision ;-)

To be fair, the linker isn't deciding to create the RWX segment - it is being 
told to do so by the linker script.  Or rather the script is not giving the
linker enough leeway to create separate code and data segments.

But either way, the thought with the warning message is that it is better
that the developer know (and ignore) about the situation, rather than live
in ignorance.

Cheers
  Nick
Comment 4 Jérôme Forissier 2022-08-05 18:41:00 UTC
(In reply to Nick Clifton from comment #3)
> (In reply to Jérôme Forissier from comment #2)
>   
> > Yep that's a reasonable thing to do in my case, but still, I think the
> > behavior is a bit weird. Again, ld deciding to create that RWX segment and
> > later complaining about its own decision ;-)
> 
> To be fair, the linker isn't deciding to create the RWX segment - it is
> being 
> told to do so by the linker script. Or rather the script is not giving the
> linker enough leeway to create separate code and data segments.

But then how is it that the LLVM linker (ld.lld) has no problem with that? Same, linker script, and even same object files... (it generates 4 LOAD segments instead of just 2).

> But either way, the thought with the warning message is that it is better
> that the developer know (and ignore) about the situation, rather than live
> in ignorance.

Agreed on that point.

-- 
Jerome
Comment 5 Andrew Pinski 2022-08-24 04:37:12 UTC
The reasoning is because the max "page size" on aarch64 is set to 64k so there is only one segment. 

Either change the " . = ALIGN((1 << (12)));" to " . = ALIGN((1 << (14)));"
Or use "-z max-page-size=4096" .
Comment 6 Andrew Pinski 2022-08-24 04:39:05 UTC
(In reply to Jérôme Forissier from comment #4)
> But then how is it that the LLVM linker (ld.lld) has no problem with that?
> Same, linker script, and even same object files... (it generates 4 LOAD
> segments instead of just 2).

Because LLVM linker is set incorrectly for the max page size. It should be set to 64k as that as Linux supports 64k page size. See comment #5 otherwise.