Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/secure/libc_stack_protector.c
39476 views
1
/* $NetBSD: stack_protector.c,v 1.4 2006/11/22 17:23:25 christos Exp $ */
2
/* $OpenBSD: stack_protector.c,v 1.10 2006/03/31 05:34:44 deraadt Exp $ */
3
/*
4
* Copyright (c) 2002 Hiroaki Etoh, Federico G. Schwindt, and Miodrag Vallat.
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
17
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
* DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
20
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
* POSSIBILITY OF SUCH DAMAGE.
27
*
28
*/
29
30
#include <sys/param.h>
31
#include <sys/sysctl.h>
32
#include <errno.h>
33
#include <link.h>
34
#include <signal.h>
35
#include <string.h>
36
#include <syslog.h>
37
#include <unistd.h>
38
#include "libc_private.h"
39
40
/*
41
* We give __guard_setup a defined priority early on so that statically linked
42
* applications have a defined priority at which __stack_chk_guard will be
43
* getting initialized. This will not matter to most applications, because
44
* they're either not usually statically linked or they simply don't do things
45
* in constructors that would be adversely affected by their positioning with
46
* respect to this initialization.
47
*/
48
static void __guard_setup(void)
49
__attribute__((__constructor__ (200), __used__));
50
51
extern long __stack_chk_guard[8];
52
extern int __sysctl(const int *name, u_int namelen, void *oldp,
53
size_t *oldlenp, void *newp, size_t newlen);
54
55
long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0};
56
static void __fail(const char *) __dead2;
57
void __stack_chk_fail(void) __dead2;
58
void __chk_fail(void) __dead2;
59
60
/*LINTED used*/
61
static void
62
__guard_setup(void)
63
{
64
static const int mib[2] = { CTL_KERN, KERN_ARND };
65
volatile long tmp_stack_chk_guard[nitems(__stack_chk_guard)];
66
size_t idx, len;
67
int error;
68
69
if (__stack_chk_guard[0] != 0)
70
return;
71
/*
72
* Avoid using functions which might have stack protection
73
* enabled, to update the __stack_chk_guard. First fetch the
74
* data into a temporal array, then do manual volatile copy to
75
* not allow optimizer to call memcpy() behind us.
76
*/
77
error = _elf_aux_info(AT_CANARY,
78
__DEQUALIFY(void *, tmp_stack_chk_guard),
79
sizeof(tmp_stack_chk_guard));
80
if (error == 0 && tmp_stack_chk_guard[0] != 0) {
81
for (idx = 0; idx < nitems(__stack_chk_guard); idx++) {
82
__stack_chk_guard[idx] = tmp_stack_chk_guard[idx];
83
tmp_stack_chk_guard[idx] = 0;
84
}
85
return;
86
}
87
88
len = sizeof(__stack_chk_guard);
89
if (__sysctl(mib, nitems(mib), __stack_chk_guard, &len, NULL, 0) ==
90
-1 || len != sizeof(__stack_chk_guard)) {
91
/* If sysctl was unsuccessful, use the "terminator canary". */
92
((unsigned char *)(void *)__stack_chk_guard)[0] = 0;
93
((unsigned char *)(void *)__stack_chk_guard)[1] = 0;
94
((unsigned char *)(void *)__stack_chk_guard)[2] = '\n';
95
((unsigned char *)(void *)__stack_chk_guard)[3] = 255;
96
}
97
}
98
99
/*ARGSUSED*/
100
static void
101
__fail(const char *msg)
102
{
103
struct sigaction sa;
104
sigset_t mask;
105
106
/* Immediately block all signal handlers from running code */
107
(void)sigfillset(&mask);
108
(void)sigdelset(&mask, SIGABRT);
109
(void)sigprocmask(SIG_BLOCK, &mask, NULL);
110
111
/* This may fail on a chroot jail... */
112
syslog(LOG_CRIT, "%s", msg);
113
114
(void)memset(&sa, 0, sizeof(sa));
115
(void)sigemptyset(&sa.sa_mask);
116
sa.sa_flags = 0;
117
sa.sa_handler = SIG_DFL;
118
(void)sigaction(SIGABRT, &sa, NULL);
119
(void)kill(getpid(), SIGABRT);
120
_exit(127);
121
}
122
123
void
124
__stack_chk_fail(void)
125
{
126
__fail("stack overflow detected; terminated");
127
}
128
129
void
130
__chk_fail(void)
131
{
132
__fail("buffer overflow detected; terminated");
133
}
134
135
#ifndef PIC
136
__weak_reference(__stack_chk_fail, __stack_chk_fail_local);
137
#endif
138
139