2007-05-19 04:31:43 +00:00
|
|
|
/* $NetBSD: stack_protector.c,v 1.4 2006/11/22 17:23:25 christos Exp $ */
|
|
|
|
/* $OpenBSD: stack_protector.c,v 1.10 2006/03/31 05:34:44 deraadt Exp $ */
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2002 Hiroaki Etoh, Federico G. Schwindt, and Miodrag Vallat.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
|
|
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/sysctl.h>
|
2010-08-17 09:13:26 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <link.h>
|
2007-05-19 04:31:43 +00:00
|
|
|
#include <signal.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <syslog.h>
|
|
|
|
#include <unistd.h>
|
2010-08-17 09:13:26 +00:00
|
|
|
#include "libc_private.h"
|
2007-05-19 04:31:43 +00:00
|
|
|
|
ssp: add a priority to the __stack_chk_guard constructor
First, this commit is a NOP on GCC <= 4.x; this decidedly doesn't work
cleanly on GCC 4.2, and it will be gone soon anyways so I chose not to dump
time into figuring out if there's a way to make it work. xtoolchain-gcc,
clocking in as GCC6, can cope with it just fine and later versions are also
generally ok with the syntax. I suspect very few users are running GCC4.2
built worlds and also experiencing potential fallout from the status quo.
For dynamically linked applications, this change also means very little.
rtld will run libc ctors before most others, so the situation is
approximately a NOP for these as well.
The real cause for this change is statically linked applications doing
almost questionable things in their constructors. qemu-user-static, for
instance, creates a thread in a global constructor for their async rcu
callbacks. In general, this works in other places-
- On OpenBSD, __stack_chk_guard is stored in an .openbsd.randomdata section
that's initialized by the kernel in the static case, or ld.so in the
dynamic case
- On Linux, __stack_chk_guard is apparently stored in TLS and such a problem
is circumvented there because the value is presumed stable in the new
thread.
On FreeBSD, the rcu thread creation ctor and __guard_setup are both unmarked
priority. qemu-user-static spins up the rcu thread prior to __guard_setup
which starts making function calls- some of these are sprinkled with the
canary. In the middle of one of these functions, __guard_setup is invoked in
the main thread and __stack_chk_guard changes- qemu-user-static is promptly
terminated for an SSP violation that didn't actually happen.
This is not an all-too-common problem. We circumvent it here by giving the
__stack_chk_guard constructor a solid priority. 200 was chosen because that
gives static applications ample range (down to 101) for working around it
if they really need to. I suspect most applications will "just work" as
expected- the default/non-prioritized flavor of __constructor__ functions
run last, and the canary is generally not expected to change as of this
point at the very least.
This took approximately three weeks of spare time debugging to pin down.
PR: 241905
2019-11-13 02:14:17 +00:00
|
|
|
/*
|
|
|
|
* We give __guard_setup a defined priority early on so that statically linked
|
|
|
|
* applications have a defined priority at which __stack_chk_guard will be
|
|
|
|
* getting initialized. This will not matter to most applications, because
|
|
|
|
* they're either not usually statically linked or they simply don't do things
|
|
|
|
* in constructors that would be adversely affected by their positioning with
|
|
|
|
* respect to this initialization.
|
2019-11-13 03:00:32 +00:00
|
|
|
*
|
|
|
|
* This conditional should be removed when GCC 4.2 is removed.
|
ssp: add a priority to the __stack_chk_guard constructor
First, this commit is a NOP on GCC <= 4.x; this decidedly doesn't work
cleanly on GCC 4.2, and it will be gone soon anyways so I chose not to dump
time into figuring out if there's a way to make it work. xtoolchain-gcc,
clocking in as GCC6, can cope with it just fine and later versions are also
generally ok with the syntax. I suspect very few users are running GCC4.2
built worlds and also experiencing potential fallout from the status quo.
For dynamically linked applications, this change also means very little.
rtld will run libc ctors before most others, so the situation is
approximately a NOP for these as well.
The real cause for this change is statically linked applications doing
almost questionable things in their constructors. qemu-user-static, for
instance, creates a thread in a global constructor for their async rcu
callbacks. In general, this works in other places-
- On OpenBSD, __stack_chk_guard is stored in an .openbsd.randomdata section
that's initialized by the kernel in the static case, or ld.so in the
dynamic case
- On Linux, __stack_chk_guard is apparently stored in TLS and such a problem
is circumvented there because the value is presumed stable in the new
thread.
On FreeBSD, the rcu thread creation ctor and __guard_setup are both unmarked
priority. qemu-user-static spins up the rcu thread prior to __guard_setup
which starts making function calls- some of these are sprinkled with the
canary. In the middle of one of these functions, __guard_setup is invoked in
the main thread and __stack_chk_guard changes- qemu-user-static is promptly
terminated for an SSP violation that didn't actually happen.
This is not an all-too-common problem. We circumvent it here by giving the
__stack_chk_guard constructor a solid priority. 200 was chosen because that
gives static applications ample range (down to 101) for working around it
if they really need to. I suspect most applications will "just work" as
expected- the default/non-prioritized flavor of __constructor__ functions
run last, and the canary is generally not expected to change as of this
point at the very least.
This took approximately three weeks of spare time debugging to pin down.
PR: 241905
2019-11-13 02:14:17 +00:00
|
|
|
*/
|
2019-11-13 18:21:06 +00:00
|
|
|
#if __has_attribute(__constructor__) || __GNUC_PREREQ__(4, 3)
|
ssp: add a priority to the __stack_chk_guard constructor
First, this commit is a NOP on GCC <= 4.x; this decidedly doesn't work
cleanly on GCC 4.2, and it will be gone soon anyways so I chose not to dump
time into figuring out if there's a way to make it work. xtoolchain-gcc,
clocking in as GCC6, can cope with it just fine and later versions are also
generally ok with the syntax. I suspect very few users are running GCC4.2
built worlds and also experiencing potential fallout from the status quo.
For dynamically linked applications, this change also means very little.
rtld will run libc ctors before most others, so the situation is
approximately a NOP for these as well.
The real cause for this change is statically linked applications doing
almost questionable things in their constructors. qemu-user-static, for
instance, creates a thread in a global constructor for their async rcu
callbacks. In general, this works in other places-
- On OpenBSD, __stack_chk_guard is stored in an .openbsd.randomdata section
that's initialized by the kernel in the static case, or ld.so in the
dynamic case
- On Linux, __stack_chk_guard is apparently stored in TLS and such a problem
is circumvented there because the value is presumed stable in the new
thread.
On FreeBSD, the rcu thread creation ctor and __guard_setup are both unmarked
priority. qemu-user-static spins up the rcu thread prior to __guard_setup
which starts making function calls- some of these are sprinkled with the
canary. In the middle of one of these functions, __guard_setup is invoked in
the main thread and __stack_chk_guard changes- qemu-user-static is promptly
terminated for an SSP violation that didn't actually happen.
This is not an all-too-common problem. We circumvent it here by giving the
__stack_chk_guard constructor a solid priority. 200 was chosen because that
gives static applications ample range (down to 101) for working around it
if they really need to. I suspect most applications will "just work" as
expected- the default/non-prioritized flavor of __constructor__ functions
run last, and the canary is generally not expected to change as of this
point at the very least.
This took approximately three weeks of spare time debugging to pin down.
PR: 241905
2019-11-13 02:14:17 +00:00
|
|
|
#define _GUARD_SETUP_CTOR_ATTR \
|
|
|
|
__attribute__((__constructor__ (200), __used__));
|
2019-11-13 03:00:32 +00:00
|
|
|
#else
|
|
|
|
#define _GUARD_SETUP_CTOR_ATTR \
|
|
|
|
__attribute__((__constructor__, __used__));
|
ssp: add a priority to the __stack_chk_guard constructor
First, this commit is a NOP on GCC <= 4.x; this decidedly doesn't work
cleanly on GCC 4.2, and it will be gone soon anyways so I chose not to dump
time into figuring out if there's a way to make it work. xtoolchain-gcc,
clocking in as GCC6, can cope with it just fine and later versions are also
generally ok with the syntax. I suspect very few users are running GCC4.2
built worlds and also experiencing potential fallout from the status quo.
For dynamically linked applications, this change also means very little.
rtld will run libc ctors before most others, so the situation is
approximately a NOP for these as well.
The real cause for this change is statically linked applications doing
almost questionable things in their constructors. qemu-user-static, for
instance, creates a thread in a global constructor for their async rcu
callbacks. In general, this works in other places-
- On OpenBSD, __stack_chk_guard is stored in an .openbsd.randomdata section
that's initialized by the kernel in the static case, or ld.so in the
dynamic case
- On Linux, __stack_chk_guard is apparently stored in TLS and such a problem
is circumvented there because the value is presumed stable in the new
thread.
On FreeBSD, the rcu thread creation ctor and __guard_setup are both unmarked
priority. qemu-user-static spins up the rcu thread prior to __guard_setup
which starts making function calls- some of these are sprinkled with the
canary. In the middle of one of these functions, __guard_setup is invoked in
the main thread and __stack_chk_guard changes- qemu-user-static is promptly
terminated for an SSP violation that didn't actually happen.
This is not an all-too-common problem. We circumvent it here by giving the
__stack_chk_guard constructor a solid priority. 200 was chosen because that
gives static applications ample range (down to 101) for working around it
if they really need to. I suspect most applications will "just work" as
expected- the default/non-prioritized flavor of __constructor__ functions
run last, and the canary is generally not expected to change as of this
point at the very least.
This took approximately three weeks of spare time debugging to pin down.
PR: 241905
2019-11-13 02:14:17 +00:00
|
|
|
#endif
|
|
|
|
|
2020-01-04 20:07:11 +00:00
|
|
|
extern long __stack_chk_guard[8];
|
2015-06-14 07:47:18 +00:00
|
|
|
extern int __sysctl(const int *name, u_int namelen, void *oldp,
|
|
|
|
size_t *oldlenp, void *newp, size_t newlen);
|
2007-05-19 04:31:43 +00:00
|
|
|
|
|
|
|
long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
ssp: add a priority to the __stack_chk_guard constructor
First, this commit is a NOP on GCC <= 4.x; this decidedly doesn't work
cleanly on GCC 4.2, and it will be gone soon anyways so I chose not to dump
time into figuring out if there's a way to make it work. xtoolchain-gcc,
clocking in as GCC6, can cope with it just fine and later versions are also
generally ok with the syntax. I suspect very few users are running GCC4.2
built worlds and also experiencing potential fallout from the status quo.
For dynamically linked applications, this change also means very little.
rtld will run libc ctors before most others, so the situation is
approximately a NOP for these as well.
The real cause for this change is statically linked applications doing
almost questionable things in their constructors. qemu-user-static, for
instance, creates a thread in a global constructor for their async rcu
callbacks. In general, this works in other places-
- On OpenBSD, __stack_chk_guard is stored in an .openbsd.randomdata section
that's initialized by the kernel in the static case, or ld.so in the
dynamic case
- On Linux, __stack_chk_guard is apparently stored in TLS and such a problem
is circumvented there because the value is presumed stable in the new
thread.
On FreeBSD, the rcu thread creation ctor and __guard_setup are both unmarked
priority. qemu-user-static spins up the rcu thread prior to __guard_setup
which starts making function calls- some of these are sprinkled with the
canary. In the middle of one of these functions, __guard_setup is invoked in
the main thread and __stack_chk_guard changes- qemu-user-static is promptly
terminated for an SSP violation that didn't actually happen.
This is not an all-too-common problem. We circumvent it here by giving the
__stack_chk_guard constructor a solid priority. 200 was chosen because that
gives static applications ample range (down to 101) for working around it
if they really need to. I suspect most applications will "just work" as
expected- the default/non-prioritized flavor of __constructor__ functions
run last, and the canary is generally not expected to change as of this
point at the very least.
This took approximately three weeks of spare time debugging to pin down.
PR: 241905
2019-11-13 02:14:17 +00:00
|
|
|
static void __guard_setup(void) _GUARD_SETUP_CTOR_ATTR;
|
2021-09-29 16:48:20 -05:00
|
|
|
static void __fail(const char *) __dead2;
|
|
|
|
void __stack_chk_fail(void) __dead2;
|
|
|
|
void __chk_fail(void) __dead2;
|
2007-05-19 04:31:43 +00:00
|
|
|
|
|
|
|
/*LINTED used*/
|
|
|
|
static void
|
|
|
|
__guard_setup(void)
|
|
|
|
{
|
2015-06-14 07:47:18 +00:00
|
|
|
static const int mib[2] = { CTL_KERN, KERN_ARND };
|
2018-04-24 15:59:39 +00:00
|
|
|
volatile long tmp_stack_chk_guard[nitems(__stack_chk_guard)];
|
2020-01-04 20:07:11 +00:00
|
|
|
size_t idx, len;
|
|
|
|
int error;
|
2007-05-19 04:31:43 +00:00
|
|
|
|
|
|
|
if (__stack_chk_guard[0] != 0)
|
|
|
|
return;
|
2018-04-24 15:59:39 +00:00
|
|
|
/*
|
|
|
|
* Avoid using functions which might have stack protection
|
|
|
|
* enabled, to update the __stack_chk_guard. First fetch the
|
|
|
|
* data into a temporal array, then do manual volatile copy to
|
|
|
|
* not allow optimizer to call memcpy() behind us.
|
|
|
|
*/
|
2020-01-04 20:07:11 +00:00
|
|
|
error = _elf_aux_info(AT_CANARY,
|
|
|
|
__DEQUALIFY(void *, tmp_stack_chk_guard),
|
2018-04-24 15:59:39 +00:00
|
|
|
sizeof(tmp_stack_chk_guard));
|
|
|
|
if (error == 0 && tmp_stack_chk_guard[0] != 0) {
|
|
|
|
for (idx = 0; idx < nitems(__stack_chk_guard); idx++) {
|
|
|
|
__stack_chk_guard[idx] = tmp_stack_chk_guard[idx];
|
|
|
|
tmp_stack_chk_guard[idx] = 0;
|
|
|
|
}
|
2010-08-17 09:13:26 +00:00
|
|
|
return;
|
2018-04-24 15:59:39 +00:00
|
|
|
}
|
2007-05-19 04:31:43 +00:00
|
|
|
|
|
|
|
len = sizeof(__stack_chk_guard);
|
2015-06-14 07:47:18 +00:00
|
|
|
if (__sysctl(mib, nitems(mib), __stack_chk_guard, &len, NULL, 0) ==
|
|
|
|
-1 || len != sizeof(__stack_chk_guard)) {
|
2007-05-19 04:31:43 +00:00
|
|
|
/* If sysctl was unsuccessful, use the "terminator canary". */
|
|
|
|
((unsigned char *)(void *)__stack_chk_guard)[0] = 0;
|
|
|
|
((unsigned char *)(void *)__stack_chk_guard)[1] = 0;
|
|
|
|
((unsigned char *)(void *)__stack_chk_guard)[2] = '\n';
|
|
|
|
((unsigned char *)(void *)__stack_chk_guard)[3] = 255;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*ARGSUSED*/
|
|
|
|
static void
|
|
|
|
__fail(const char *msg)
|
|
|
|
{
|
|
|
|
struct sigaction sa;
|
|
|
|
sigset_t mask;
|
|
|
|
|
|
|
|
/* Immediately block all signal handlers from running code */
|
|
|
|
(void)sigfillset(&mask);
|
|
|
|
(void)sigdelset(&mask, SIGABRT);
|
|
|
|
(void)sigprocmask(SIG_BLOCK, &mask, NULL);
|
|
|
|
|
|
|
|
/* This may fail on a chroot jail... */
|
2010-10-13 16:57:06 +00:00
|
|
|
syslog(LOG_CRIT, "%s", msg);
|
2007-05-19 04:31:43 +00:00
|
|
|
|
|
|
|
(void)memset(&sa, 0, sizeof(sa));
|
|
|
|
(void)sigemptyset(&sa.sa_mask);
|
|
|
|
sa.sa_flags = 0;
|
|
|
|
sa.sa_handler = SIG_DFL;
|
|
|
|
(void)sigaction(SIGABRT, &sa, NULL);
|
|
|
|
(void)kill(getpid(), SIGABRT);
|
|
|
|
_exit(127);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__stack_chk_fail(void)
|
|
|
|
{
|
|
|
|
__fail("stack overflow detected; terminated");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__chk_fail(void)
|
|
|
|
{
|
|
|
|
__fail("buffer overflow detected; terminated");
|
|
|
|
}
|
|
|
|
|
2014-11-25 03:50:31 +00:00
|
|
|
#ifndef PIC
|
2009-09-17 13:21:53 +00:00
|
|
|
__weak_reference(__stack_chk_fail, __stack_chk_fail_local);
|
|
|
|
#endif
|