Petr Hosek via llvm-dev
2017-May-17 20:11 UTC
[llvm-dev] [lld][ELF] Add option to make .dynamic read only
The motivation is not only memory savings but also security: can-never-be-written is strictly better than RELRO in all cases. The biggest win is when .dynamic is the sole reason for having a writable segment at all. The distinction is fairly small for exploitability, but not negligible. LLD already has several command-line options that are not supported by or are different from ld or gold, so this wouldn't be the first one (and probably not the last). If LLD supported per-OS configuration, we would make this default for Fuchsia and wouldn't need the new option, but since these don't exists, it's something we would handle through the Clang driver. On Tue, May 16, 2017 at 7:12 PM Rui Ueyama via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Thank you for confirming. But one page is too small, no? I think we are > not that picky about memory footprint. For example, LLD and gold's outputs > are usually slightly different in size due to various reasons such as the > differences how they order sections, common symbols, etc., but no one seems > to care about that kind of negligible differences. Merging DT_MIPS_RLD_MAP > into DT_DEBUG_INDIRECT seems like a good change, but adding a new command > option to save one page at runtime seems overkill to me. (But I don't know > much about Fuchsia, so correct me if I'm wrong.) > > On Tue, May 16, 2017 at 6:08 PM, Jake Ehrlich via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > >> Your understanding is correct. It saves a small number of physical pages. >> It's strictly better even if it's only a little bit better. >> >> >> On Tue, May 16, 2017, 5:14 PM Rui Ueyama <ruiu at google.com> wrote: >> >>> Hi Jake, >>> >>> Thank you for sending this to llvm-dev! >>> >>> If I understand correctly, your motivation to add an option to make >>> .dynamic sections read-only is to share .dynamic sections in memory so that >>> each process executing the same file doesn't have to have a separate copy >>> of a .dynamic section. But you would usually save just one page or two by >>> doing that because .dynamic sections are usually very small. Even if they >>> are large, they could be shared between processes by copy-on-write. What am >>> I missing? >>> >>> On Tue, May 16, 2017 at 4:31 PM, Jake Ehrlich via llvm-dev < >>> llvm-dev at lists.llvm.org> wrote: >>> >>>> Hi, >>>> >>>> This is a proposal to add an option to lld that forces .dynamic >>>> sections to be read-only. >>>> >>>> The .dynamic section is almost read-only except for the DT_DEBUG entry >>>> which requires the dynamic linker to modify a word. MIPS has long since had >>>> a solution to this using the DT_MIPS_RLD_MAP entry to give a pointer to >>>> another section which is writable. It would be nice to have this >>>> functionality on other targets as well however. Right now many dynamic >>>> linkers do not support this layer of indirection so this can't happen by >>>> default, it must be an option. Currently .dynamic gets mapped to a >>>> PT_GNU_RELRO section. PT_GNU_RELRO sections are not shared between >>>> instances of a executable however. It would be a nice optimization to share >>>> the .dynamic section of an application where possible. In particular we >>>> would like to have this option for Fuchsia. Other dynamic linkers, like >>>> musl, already have some support for this on non-MIPS targets as seen here: >>>> http://git.musl-libc.org/cgit/musl/tree/ldso/dynlink.c#n1629. In >>>> particular the DT_DEBUG_INDIRECT entry is recognized. >>>> >>>> This change would refactor code that already exists for MIPS specific >>>> .dynamic sections and make them available to other targets. Mostly this >>>> would just require renaming some things and moving a few lines around. The >>>> biggest part of this change would be to add the flag. I propose it be a -z >>>> keyword called "rodynamic". >>>> >>>> I have already made a patch for this change which can be seen here: >>>> https://reviews.llvm.org/D33251 >>>> >>>> Best, >>>> Jake >>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> llvm-dev at lists.llvm.org >>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>>> >>>> >>> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >> > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170517/5abbae62/attachment.html>
Rui Ueyama via llvm-dev
2017-May-17 20:32 UTC
[llvm-dev] [lld][ELF] Add option to make .dynamic read only
On Wed, May 17, 2017 at 1:11 PM, Petr Hosek <phosek at chromium.org> wrote:> The motivation is not only memory savings but also security: > can-never-be-written is strictly better than RELRO in all cases. The > biggest win is when .dynamic is the sole reason for having a writable > segment at all. The distinction is fairly small for exploitability, but not > negligible. >I'm not even sure if it is strictly better to make .dynamic read-only by default is better than relro. It seems almost the same to me. What are attack scenario you can think of in which you can exploit only when .dynamic sections are read-only from beginning? Maybe Fuchsia OS does something special for executable that contain read-only sections only? LLD already has several command-line options that are not supported by or> are different from ld or gold, so this wouldn't be the first one (and > probably not the last). If LLD supported per-OS configuration, we would > make this default for Fuchsia and wouldn't need the new option, but since > these don't exists, it's something we would handle through the Clang driver. >Yes, we have bunch of options that are not supported by GNU linkers, particularly for LTO. So adding new options is fine as long as doing it makes sense. But the bar should be higher than implementing compatible options. Having no host OS-specific default options in the linker is more like a feature than a lack of a feature. We rely on compilers to give appropriate options to us. That makes the linker's behavior more predictable, and it also makes it very easy to support cross-linking. On Tue, May 16, 2017 at 7:12 PM Rui Ueyama via llvm-dev <> llvm-dev at lists.llvm.org> wrote: > >> Thank you for confirming. But one page is too small, no? I think we are >> not that picky about memory footprint. For example, LLD and gold's outputs >> are usually slightly different in size due to various reasons such as the >> differences how they order sections, common symbols, etc., but no one seems >> to care about that kind of negligible differences. Merging DT_MIPS_RLD_MAP >> into DT_DEBUG_INDIRECT seems like a good change, but adding a new command >> option to save one page at runtime seems overkill to me. (But I don't know >> much about Fuchsia, so correct me if I'm wrong.) >> >> On Tue, May 16, 2017 at 6:08 PM, Jake Ehrlich via llvm-dev < >> llvm-dev at lists.llvm.org> wrote: >> >>> Your understanding is correct. It saves a small number of physical >>> pages. It's strictly better even if it's only a little bit better. >>> >>> >>> On Tue, May 16, 2017, 5:14 PM Rui Ueyama <ruiu at google.com> wrote: >>> >>>> Hi Jake, >>>> >>>> Thank you for sending this to llvm-dev! >>>> >>>> If I understand correctly, your motivation to add an option to make >>>> .dynamic sections read-only is to share .dynamic sections in memory so that >>>> each process executing the same file doesn't have to have a separate copy >>>> of a .dynamic section. But you would usually save just one page or two by >>>> doing that because .dynamic sections are usually very small. Even if they >>>> are large, they could be shared between processes by copy-on-write. What am >>>> I missing? >>>> >>>> On Tue, May 16, 2017 at 4:31 PM, Jake Ehrlich via llvm-dev < >>>> llvm-dev at lists.llvm.org> wrote: >>>> >>>>> Hi, >>>>> >>>>> This is a proposal to add an option to lld that forces .dynamic >>>>> sections to be read-only. >>>>> >>>>> The .dynamic section is almost read-only except for the DT_DEBUG entry >>>>> which requires the dynamic linker to modify a word. MIPS has long since had >>>>> a solution to this using the DT_MIPS_RLD_MAP entry to give a pointer to >>>>> another section which is writable. It would be nice to have this >>>>> functionality on other targets as well however. Right now many dynamic >>>>> linkers do not support this layer of indirection so this can't happen by >>>>> default, it must be an option. Currently .dynamic gets mapped to a >>>>> PT_GNU_RELRO section. PT_GNU_RELRO sections are not shared between >>>>> instances of a executable however. It would be a nice optimization to share >>>>> the .dynamic section of an application where possible. In particular we >>>>> would like to have this option for Fuchsia. Other dynamic linkers, like >>>>> musl, already have some support for this on non-MIPS targets as seen here: >>>>> http://git.musl-libc.org/cgit/musl/tree/ldso/dynlink.c#n1629. In >>>>> particular the DT_DEBUG_INDIRECT entry is recognized. >>>>> >>>>> This change would refactor code that already exists for MIPS specific >>>>> .dynamic sections and make them available to other targets. Mostly this >>>>> would just require renaming some things and moving a few lines around. The >>>>> biggest part of this change would be to add the flag. I propose it be a -z >>>>> keyword called "rodynamic". >>>>> >>>>> I have already made a patch for this change which can be seen here: >>>>> https://reviews.llvm.org/D33251 >>>>> >>>>> Best, >>>>> Jake >>>>> >>>>> _______________________________________________ >>>>> LLVM Developers mailing list >>>>> llvm-dev at lists.llvm.org >>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>>>> >>>>> >>>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>> >>> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170517/be6640ec/attachment.html>
Peter Collingbourne via llvm-dev
2017-May-17 20:44 UTC
[llvm-dev] [lld][ELF] Add option to make .dynamic read only
On Wed, May 17, 2017 at 1:32 PM, Rui Ueyama via llvm-dev < llvm-dev at lists.llvm.org> wrote:> On Wed, May 17, 2017 at 1:11 PM, Petr Hosek <phosek at chromium.org> wrote: > >> The motivation is not only memory savings but also security: >> can-never-be-written is strictly better than RELRO in all cases. The >> biggest win is when .dynamic is the sole reason for having a writable >> segment at all. The distinction is fairly small for exploitability, but not >> negligible. >> > > I'm not even sure if it is strictly better to make .dynamic read-only by > default is better than relro. It seems almost the same to me. What are > attack scenario you can think of in which you can exploit only when > .dynamic sections are read-only from beginning? >Maybe Fuchsia OS does something special for executable that contain> read-only sections only? >I'd be interested in this as well, CFI relies on relro for its vtable protection to work. Is the issue just the window of opportunity between mapping the pages and protecting them?>> LLD already has several command-line options that are not supported by or >> are different from ld or gold, so this wouldn't be the first one (and >> probably not the last). If LLD supported per-OS configuration, we would >> make this default for Fuchsia and wouldn't need the new option, but since >> these don't exists, it's something we would handle through the Clang driver. >> > > Yes, we have bunch of options that are not supported by GNU linkers, > particularly for LTO. So adding new options is fine as long as doing it > makes sense. But the bar should be higher than implementing compatible > options. > > Having no host OS-specific default options in the linker is more like a > feature than a lack of a feature. We rely on compilers to give appropriate > options to us. That makes the linker's behavior more predictable, and it > also makes it very easy to support cross-linking. >Note that you could avoid needing to add a new flag by defining a new ELFOSABI for Fuchsia and making this behaviour conditional on it. Peter> > On Tue, May 16, 2017 at 7:12 PM Rui Ueyama via llvm-dev < >> llvm-dev at lists.llvm.org> wrote: >> >>> Thank you for confirming. But one page is too small, no? I think we are >>> not that picky about memory footprint. For example, LLD and gold's outputs >>> are usually slightly different in size due to various reasons such as the >>> differences how they order sections, common symbols, etc., but no one seems >>> to care about that kind of negligible differences. Merging DT_MIPS_RLD_MAP >>> into DT_DEBUG_INDIRECT seems like a good change, but adding a new command >>> option to save one page at runtime seems overkill to me. (But I don't know >>> much about Fuchsia, so correct me if I'm wrong.) >>> >>> On Tue, May 16, 2017 at 6:08 PM, Jake Ehrlich via llvm-dev < >>> llvm-dev at lists.llvm.org> wrote: >>> >>>> Your understanding is correct. It saves a small number of physical >>>> pages. It's strictly better even if it's only a little bit better. >>>> >>>> >>>> On Tue, May 16, 2017, 5:14 PM Rui Ueyama <ruiu at google.com> wrote: >>>> >>>>> Hi Jake, >>>>> >>>>> Thank you for sending this to llvm-dev! >>>>> >>>>> If I understand correctly, your motivation to add an option to make >>>>> .dynamic sections read-only is to share .dynamic sections in memory so that >>>>> each process executing the same file doesn't have to have a separate copy >>>>> of a .dynamic section. But you would usually save just one page or two by >>>>> doing that because .dynamic sections are usually very small. Even if they >>>>> are large, they could be shared between processes by copy-on-write. What am >>>>> I missing? >>>>> >>>>> On Tue, May 16, 2017 at 4:31 PM, Jake Ehrlich via llvm-dev < >>>>> llvm-dev at lists.llvm.org> wrote: >>>>> >>>>>> Hi, >>>>>> >>>>>> This is a proposal to add an option to lld that forces .dynamic >>>>>> sections to be read-only. >>>>>> >>>>>> The .dynamic section is almost read-only except for the DT_DEBUG >>>>>> entry which requires the dynamic linker to modify a word. MIPS has long >>>>>> since had a solution to this using the DT_MIPS_RLD_MAP entry to give a >>>>>> pointer to another section which is writable. It would be nice to have this >>>>>> functionality on other targets as well however. Right now many dynamic >>>>>> linkers do not support this layer of indirection so this can't happen by >>>>>> default, it must be an option. Currently .dynamic gets mapped to a >>>>>> PT_GNU_RELRO section. PT_GNU_RELRO sections are not shared between >>>>>> instances of a executable however. It would be a nice optimization to share >>>>>> the .dynamic section of an application where possible. In particular we >>>>>> would like to have this option for Fuchsia. Other dynamic linkers, like >>>>>> musl, already have some support for this on non-MIPS targets as seen here: >>>>>> http://git.musl-libc.org/cgit/musl/tree/ldso/dynlink.c#n1629. In >>>>>> particular the DT_DEBUG_INDIRECT entry is recognized. >>>>>> >>>>>> This change would refactor code that already exists for MIPS specific >>>>>> .dynamic sections and make them available to other targets. Mostly this >>>>>> would just require renaming some things and moving a few lines around. The >>>>>> biggest part of this change would be to add the flag. I propose it be a -z >>>>>> keyword called "rodynamic". >>>>>> >>>>>> I have already made a patch for this change which can be seen here: >>>>>> https://reviews.llvm.org/D33251 >>>>>> >>>>>> Best, >>>>>> Jake >>>>>> >>>>>> _______________________________________________ >>>>>> LLVM Developers mailing list >>>>>> llvm-dev at lists.llvm.org >>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>>>>> >>>>>> >>>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> llvm-dev at lists.llvm.org >>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>>> >>>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>> >> > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > >-- -- Peter -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170517/6b43c9cd/attachment-0001.html>