This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] nptl: change default stack guard size of threads


On Tue, Dec 12, 2017 at 11:42:51AM +0000, Szabolcs Nagy wrote:
> On 11/12/17 23:49, Jeff Law wrote:
> > On 12/05/2017 03:55 AM, James Greenhalgh wrote:
> >>>> GCC needs to emit probe intervals for the smallest supported page size 
> >>>> on the the target architecture.  If it does not do that, we end up in 
> >>>> trouble on the glibc side.
> >>
> >> This is where I may have a misunderstanding, why would it require probing
> >> at the smallest page size, rather than probing at a multiple of the guard
> >> size? It is very likely I'm missing something here as I don't know the glibc
> >> side of this at all.
> > I'm not sure where that statement comes from either.  I guess the
> > concern is someone could boot a kernel with a smaller page size and
> > perhaps the kernel/glibc create their guards based on # pages rather
> > than absolute size.  Thus booting a kernel with a smaller pagesize would
> > code with less protection.
> 
> historically posix required a single page guard at the
> end of thread stacks, that's what all existing libcs
> implement and glibc internally assumes this at several
> places where stack/guard size accounting happens.
> (so larger guard is not conform to posix-2004, only
> to >=posix-2008)

I don't follow your reasoning about how a conformance distinction can
be made here. There is no formal model for "does not have additional
guard pages"; that's just an implementation detail of the memory
layout. As a thought experiment, a hardened kernel might always put
giant randomly-perturbed guard zones before and after every mmap.

If the default size was actually specified to be one page in old POSIX
and pthread_attr_getstacksize exposed a larger size for the default, I
suppose this could be a conformance distinction, but I'm not aware of
such a requirement.

> users can also set the guard size explicitly when creating
> threads (at least openjdk and erlang do this for threads
> that call c code) and that's not something glibc can change:
> it is allowed to round this up to pagesize but not to
> some arbitrary larger value.

Likewise I think this is mistaken, for the above reason. If the
rounding-up happens at pthread_create time rather than when setting
the attribute, it's certainly not observable as a conformance
distinction. Of course it is a QoI distinction in both directions:

- Rounding up reduces the available virtual memory space, possibly
  limiting the size of an application (detriment to QoI).

- Rounding up may limit the impact of stack overflow bugs to a crash
  rather than something more severe (QoI advantage).

There are also other safety improvements that could be made at the
expense of virtual memory space and run time costs. For instance in
musl I've considered a hardening option to put guard pages (maybe
repeating the requested guard size? or just one page?) between the end
of the stack and the TLS area so that stack-based overflows can't
clobber TLS/TCB. But this is rather costly since it doubles the number
of kernel VMAs needed, so I'm very hesitant to do it without evidence
that it would thwart real-world vulns.

> glibc has another problem that it does stack accounting
> incorrectly and thus increasing the guard size can easily
> make existing code fail with stack overflow and fixing
> this is non-trivial since many users already expect the
> buggy behaviour (with glibc specific workarounds)

This indeed needs to be fixed, whatever is done with regards to
default guard size.

Rich


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]