diff mbox

quagga: disable PIE on ARC

Message ID 1436436011-8126-1-git-send-email-abrodkin@synopsys.com
State Accepted
Headers show

Commit Message

Alexey Brodkin July 9, 2015, 10 a.m. UTC
Even though ARC gcc understands "-pie" option and attempts to generate
PIE binaries as of today PIE is not really supported for user-space
applications.

So we disable PIE detection if building for ARC.
That fixes http://autobuild.buildroot.net/results/ca0/ca0b1e271f29d7639b6a6e895472a35e2c1d8aba
and also prevents execution of non-supported PIE binary in runtime.

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 package/quagga/quagga.mk | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Thomas Petazzoni July 9, 2015, 8:14 p.m. UTC | #1
Dear Alexey Brodkin,

On Thu,  9 Jul 2015 13:00:11 +0300, Alexey Brodkin wrote:
> Even though ARC gcc understands "-pie" option and attempts to generate
> PIE binaries as of today PIE is not really supported for user-space
> applications.
> 
> So we disable PIE detection if building for ARC.
> That fixes http://autobuild.buildroot.net/results/ca0/ca0b1e271f29d7639b6a6e895472a35e2c1d8aba
> and also prevents execution of non-supported PIE binary in runtime.
> 
> Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
> Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> ---
>  package/quagga/quagga.mk | 4 ++++
>  1 file changed, 4 insertions(+)

Applied, thanks.

Thomas
Arnout Vandecappelle July 9, 2015, 9:30 p.m. UTC | #2
On 07/09/15 12:00, Alexey Brodkin wrote:
> Even though ARC gcc understands "-pie" option and attempts to generate
> PIE binaries as of today PIE is not really supported for user-space
> applications.

 Wouldn't it be better then if we would patch gcc to remove the -pie option?
That removes all these special cases in one fell swoop, and is much easier to
un-disable once PIE _is_ supported for ARC gcc.

 Regards,
 Arnout
Thomas Petazzoni July 10, 2015, 6:44 a.m. UTC | #3
Arnout, Alexey,

On Thu, 9 Jul 2015 23:30:14 +0200, Arnout Vandecappelle wrote:
> On 07/09/15 12:00, Alexey Brodkin wrote:
> > Even though ARC gcc understands "-pie" option and attempts to generate
> > PIE binaries as of today PIE is not really supported for user-space
> > applications.
> 
>  Wouldn't it be better then if we would patch gcc to remove the -pie option?
> That removes all these special cases in one fell swoop, and is much easier to
> un-disable once PIE _is_ supported for ARC gcc.

It would indeed be a lot better.

Best regards,

Thomas
Alexey Brodkin July 10, 2015, 8:12 a.m. UTC | #4
Hi Thomas, Arnout,

On Fri, 2015-07-10 at 08:44 +0200, Thomas Petazzoni wrote:
> Arnout, Alexey,
> 
> On Thu, 9 Jul 2015 23:30:14 +0200, Arnout Vandecappelle wrote:
> > On 07/09/15 12:00, Alexey Brodkin wrote:
> > > Even though ARC gcc understands "-pie" option and attempts to generate
> > > PIE binaries as of today PIE is not really supported for user-space
> > > applications.
> > 
> >  Wouldn't it be better then if we would patch gcc to remove the -pie option?
> > That removes all these special cases in one fell swoop, and is much easier to
> > un-disable once PIE _is_ supported for ARC gcc.
> 
> It would indeed be a lot better.

I would agree with that proposal but... TL;DR below :)

Actually at the moment the only real "user" of PIE (in case of ARC)
is U-Boot. U-Boot (by its generic design which is architecture independent)
does "self-relocation" on early boot.

Scenario is simple.

We assume that U-Boot executable is located in ROM after power-up
and what's more important has access to very limited amount of RAM.

For example on Intel machines U-Boot uses locked cache as pre-relocation RAM.
Other examples could be on-chip RAM etc.

So what happens U-Boot does very-very basic initialization including say DDR
init and then U-Boot copies itself in DDR (in the very end of available
memory so it may then load something useful in the beginning of DDR for
example Linux kernel or other executable).

But to have an ability to execute relocated/moved code and access data
that was also moved it's required to fixup locations of functions and data
units that are accessed directly (i.e. by its address compared to relative
offset from current location).

Note that U-Boot copies all sections be it .data, .text,
.rel etc. except .bss which is supposed to be used only after relocation
and so its area just gets zeroed during "relocation".

And what happens U-Boot is linked with "-pae" which leads to a fact
that executable contains a special section called usually .rel or .rela
where resides information about all directly addressed units.

During relocation U-Boot once all required sections were copied from
flash/ROM to DDR reads data from .rel/.rela updates all directly used
addresses (by simple addition of offset between address in flash/ROM and
new location in DDR).

What is important PIC (Position-Independent Code) is not enough here
because it only cares about code but not data. While PIE
(Position-Independent Executable) cares about both code and data.

Now we have U-Boot for ARC and it could be built from any recent upstream
U-Boot release. And we want people to have ability to build U-Boot with
Buildroot.

But as we know Buildroot builds only one toolchain for all purposes.
Even for building Linux kernel or U-Boot while those are bare-metal
executables compared to user-space apps that are normally built by
*libc-toolchain.

In other words if we disable PIE in Buildroot's toolchain there will be
no way to build U-Boot for ARC. And that's not what we want.

Note that U-Boot needs PIE not only on ARC but on x86, ARM and MIPS.
So that's not unique "feature" or ARC. Some arches still use PIC in
U-Boot but that causes problems here and there, requiring to patch
offsets manually in each and every driver etc instead of using gcc,
grep for CONFIG_NEEDS_MANUAL_RELOC if of any interest :)

Hopefully my explanation makes some sense.

If you guys have any thought on how to solve that problem better please
shout.

-Alexey
Arnout Vandecappelle July 10, 2015, 10:08 a.m. UTC | #5
On 07/10/15 10:12, Alexey Brodkin wrote:
[snip]

 Thanks for the detailed explanation!

> In other words if we disable PIE in Buildroot's toolchain there will be
> no way to build U-Boot for ARC. And that's not what we want.

 It's probably getting complicated, but we could add either another option or an
environment variable to enable PIE again. E.g. if it's an envrionment variable,
then we can do for packages that we know do *not* break with ARC-PIE:

ifneq ($(BR2_arc),)
UBOOT_MAKE_ENV += GCC_REALLY_SUPPORT_PIE=1
endif

(and of course make sure that UBOOT_MAKE_ENV is used, which is currently not the
case in uboot.mk).


 Question is: is that more complicated that the current per-package workarounds
or not?

 Regards,
 Arnout

> 
> Note that U-Boot needs PIE not only on ARC but on x86, ARM and MIPS.
> So that's not unique "feature" or ARC. Some arches still use PIC in
> U-Boot but that causes problems here and there, requiring to patch
> offsets manually in each and every driver etc instead of using gcc,
> grep for CONFIG_NEEDS_MANUAL_RELOC if of any interest :)
> 
> Hopefully my explanation makes some sense.
> 
> If you guys have any thought on how to solve that problem better please
> shout.
> 
> -Alexey
>
Alexey Brodkin July 10, 2015, 11:28 a.m. UTC | #6
Hi Arnout,

On Fri, 2015-07-10 at 12:08 +0200, Arnout Vandecappelle wrote:
> On 07/10/15 10:12, Alexey Brodkin wrote:
> [snip]
> 
>  Thanks for the detailed explanation!
> 
> > In other words if we disable PIE in Buildroot's toolchain there will be
> > no way to build U-Boot for ARC. And that's not what we want.
> 
>  It's probably getting complicated, but we could add either another option or an
> environment variable to enable PIE again. E.g. if it's an envrionment variable,
> then we can do for packages that we know do *not* break with ARC-PIE:
> 
> ifneq ($(BR2_arc),)
> UBOOT_MAKE_ENV += GCC_REALLY_SUPPORT_PIE=1
> endif

We may add that new definition but the question is how it is supposed to work?
My understanding is once we have gcc built with PIE support it [gcc] will happily
accept "-pie" flag in command-line and will generate output accordingly.

And we don't know which software packages use PIE or may use (depending on autoconf
detection).

So the only real solution is to make sure GCC doesn't even accept "-pie" option.
I assume it's possible to do while we're building GCC itself. But if we do this
we'll a toolchain that cannot generate PIE executables and there will be no way to
build U-Boot any longer.

Probably I'm missing something here and you guys may correct me.

>  Question is: is that more complicated that the current per-package workarounds
> or not?

I really don't like that approach with fixing every package that may use PIE
but since I don't see any other solution (until PIE gets fixed in both ARc GCC
and runtime software) I have to go that way.

-Alexey
Arnout Vandecappelle July 10, 2015, 12:21 p.m. UTC | #7
On 07/10/15 13:28, Alexey Brodkin wrote:
> Hi Arnout,
> 
> On Fri, 2015-07-10 at 12:08 +0200, Arnout Vandecappelle wrote:
>> On 07/10/15 10:12, Alexey Brodkin wrote:
>> [snip]
>>
>>  Thanks for the detailed explanation!
>>
>>> In other words if we disable PIE in Buildroot's toolchain there will be
>>> no way to build U-Boot for ARC. And that's not what we want.
>>
>>  It's probably getting complicated, but we could add either another option or an
>> environment variable to enable PIE again. E.g. if it's an envrionment variable,
>> then we can do for packages that we know do *not* break with ARC-PIE:
>>
>> ifneq ($(BR2_arc),)
>> UBOOT_MAKE_ENV += GCC_REALLY_SUPPORT_PIE=1
>> endif
> 
> We may add that new definition but the question is how it is supposed to work?
> My understanding is once we have gcc built with PIE support it [gcc] will happily
> accept "-pie" flag in command-line and will generate output accordingly.

 What I mean is that we patch gcc and only support the pie option if that magic
environment variable is set.

 But looking at the source, that's not going to be easy since the whole command
line parsing is abstracted in a way that makes it difficult to hack something
like that.

 Perhaps another solution is that we disable -pie in the spec file, and pass an
alternative spec file which does have pie support in U-Boot:

UBOOT_MAKE_OPTS += \
	CC="$(TARGET_CC) -specs=path-to-specfile-with-pie"


 Regards,
 Arnout
Thomas Petazzoni July 10, 2015, 1:08 p.m. UTC | #8
Dear Arnout Vandecappelle,

On Fri, 10 Jul 2015 14:21:02 +0200, Arnout Vandecappelle wrote:

>  What I mean is that we patch gcc and only support the pie option if that magic
> environment variable is set.
> 
>  But looking at the source, that's not going to be easy since the whole command
> line parsing is abstracted in a way that makes it difficult to hack something
> like that.
> 
>  Perhaps another solution is that we disable -pie in the spec file, and pass an
> alternative spec file which does have pie support in U-Boot:
> 
> UBOOT_MAKE_OPTS += \
> 	CC="$(TARGET_CC) -specs=path-to-specfile-with-pie"

In the end, this seems quite complicated. Not that many packages try to
build their executables as PIE, so maybe handling that on a per-package
basis is easier / less hacky.

Thomas
Arnout Vandecappelle July 10, 2015, 10:05 p.m. UTC | #9
On 07/10/15 15:08, Thomas Petazzoni wrote:
> Dear Arnout Vandecappelle,
> 
> On Fri, 10 Jul 2015 14:21:02 +0200, Arnout Vandecappelle wrote:
> 
>>  What I mean is that we patch gcc and only support the pie option if that magic
>> environment variable is set.
>>
>>  But looking at the source, that's not going to be easy since the whole command
>> line parsing is abstracted in a way that makes it difficult to hack something
>> like that.
>>
>>  Perhaps another solution is that we disable -pie in the spec file, and pass an
>> alternative spec file which does have pie support in U-Boot:
>>
>> UBOOT_MAKE_OPTS += \
>> 	CC="$(TARGET_CC) -specs=path-to-specfile-with-pie"
> 
> In the end, this seems quite complicated. Not that many packages try to
> build their executables as PIE, so maybe handling that on a per-package
> basis is easier / less hacky.

 Less hacky for sure.

 And at this point probably also easier, since probably most of them have
already been handled.

 Regards,
 Arnout
diff mbox

Patch

diff --git a/package/quagga/quagga.mk b/package/quagga/quagga.mk
index 756d6e0..ce1d34b 100644
--- a/package/quagga/quagga.mk
+++ b/package/quagga/quagga.mk
@@ -39,4 +39,8 @@  else
 QUAGGA_CONF_OPTS += --disable-vtysh
 endif
 
+ifeq ($(BR2_arc),y)
+QUAGGA_CONF_OPTS += --disable-pie
+endif
+
 $(eval $(autotools-package))