Fix stack memory protection on targets where the stack grows upward
Commit Message
The tst-cputimer1 test fails on hppa. Using strace to look at the system calls generated by the test,
I observed that there is a mprotect call that passes a non page-aligned addr argument and it fails
with the error EINVAL.
The attached change aligns the old and new guard addresses to page boundaries and fixes the
failing mprotect call.
A version of this patch, hppa/local-stack-grows-up.diff, has been installed in Debian for a long time.
However, the old and new guard values were reversed in the compare. As a result, the mprotect call
was skipped. This versions checks that the new_guard value is greater than the old_guard value.
Please install.
Dave
--
John David Anglin dave.anglin@bell.net
2017-04-16 John David Anglin <danglin@gcc.gnu.org>
* nptl/allocatestack.c (allocate_stack): Align old and new guard
addresses to page boundaries when the stack grows up.
Comments
On Apr 16 2017, John David Anglin <dave.anglin@bell.net> wrote:
> + char *new_guard = (char *)(((uintptr_t) pd - guardsize) & ~pagesize_m1);
> + char *old_guard = (char *)(((uintptr_t) pd - pd->guardsize) & ~pagesize_m1);
The lines are too long.
Andreas.
* John David Anglin:
> #elif _STACK_GROWS_UP
> - if (mprotect ((char *) pd - pd->guardsize,
> - pd->guardsize - guardsize, prot) != 0)
> + char *new_guard = (char *)(((uintptr_t) pd - guardsize) & ~pagesize_m1);
> + char *old_guard = (char *)(((uintptr_t) pd - pd->guardsize) & ~pagesize_m1);
> + /* The guard size difference might be > 0, but once rounded
> + to the nearest page the size difference might be zero. */
> + if (new_guard > old_guard
> + && mprotect (old_guard, new_guard - old_guard, prot) != 0)
> goto mprot_error;
> #endif
>
This is essentially HPPA-specific code, right? So I guess we can do
whatever it takes there.
On 2017-04-16, at 5:27 PM, Florian Weimer wrote:
> This is essentially HPPA-specific code, right? So I guess we can do
> whatever it takes there.
I believe the metag architecture also has a stack that grows up.
--
John David Anglin dave.anglin@bell.net
* John David Anglin:
> On 2017-04-16, at 5:27 PM, Florian Weimer wrote:
>
>> This is essentially HPPA-specific code, right? So I guess we can do
>> whatever it takes there.
>
> I believe the metag architecture also has a stack that grows up.
I'm sure there are others, but HPPA is the only one with a glibc port.
On 2017-04-17, at 2:57 AM, Florian Weimer wrote:
> * John David Anglin:
>
>> On 2017-04-16, at 5:27 PM, Florian Weimer wrote:
>>
>>> This is essentially HPPA-specific code, right? So I guess we can do
>>> whatever it takes there.
>>
>> I believe the metag architecture also has a stack that grows up.
>
> I'm sure there are others, but HPPA is the only one with a glibc port.
Correct.
--
John David Anglin dave.anglin@bell.net
@@ -647,8 +647,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
prot) != 0)
goto mprot_error;
#elif _STACK_GROWS_UP
- if (mprotect ((char *) pd - pd->guardsize,
- pd->guardsize - guardsize, prot) != 0)
+ char *new_guard = (char *)(((uintptr_t) pd - guardsize) & ~pagesize_m1);
+ char *old_guard = (char *)(((uintptr_t) pd - pd->guardsize) & ~pagesize_m1);
+ /* The guard size difference might be > 0, but once rounded
+ to the nearest page the size difference might be zero. */
+ if (new_guard > old_guard
+ && mprotect (old_guard, new_guard - old_guard, prot) != 0)
goto mprot_error;
#endif