mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-11 03:44:38 +08:00
902c755930
Recently, mingw-w64 has got updated <msxml.h> from Wine which is included indirectly by <windows.h> if `WIN32_LEAN_AND_MEAN` is not defined. The `IXMLDOMDocument` class has a member function named `abort()`, which gets affected by our `abort()` macro in "system.h". `WIN32_LEAN_AND_MEAN` should, nevertheless, always be defined. This can exclude 'APIs such as Cryptography, DDE, RPC, Shell, and Windows Sockets' [1], and speed up compilation of these files a bit. [1] https://learn.microsoft.com/en-us/windows/win32/winprog/using-the-windows-headers gcc/ PR middle-end/108300 * config/xtensa/xtensa-dynconfig.c: Define `WIN32_LEAN_AND_MEAN` before <windows.h>. * diagnostic-color.cc: Likewise. * plugin.cc: Likewise. * prefix.cc: Likewise. gcc/ada/ PR middle-end/108300 * adaint.c: Define `WIN32_LEAN_AND_MEAN` before `#include <windows.h>`. * cio.c: Likewise. * ctrl_c.c: Likewise. * expect.c: Likewise. * gsocket.h: Likewise. * mingw32.h: Likewise. * mkdir.c: Likewise. * rtfinal.c: Likewise. * rtinit.c: Likewise. * seh_init.c: Likewise. * sysdep.c: Likewise. * terminals.c: Likewise. * tracebak.c: Likewise. gcc/jit/ PR middle-end/108300 * jit-w32.h: Define `WIN32_LEAN_AND_MEAN` before <windows.h>. libatomic/ PR middle-end/108300 * config/mingw/lock.c: Define `WIN32_LEAN_AND_MEAN` before <windows.h>. libffi/ PR middle-end/108300 * src/aarch64/ffi.c: Define `WIN32_LEAN_AND_MEAN` before <windows.h>. libgcc/ PR middle-end/108300 * config/i386/enable-execute-stack-mingw32.c: Define `WIN32_LEAN_AND_MEAN` before <windows.h>. * libgcc2.c: Likewise. * unwind-generic.h: Likewise. libgfortran/ PR middle-end/108300 * intrinsics/sleep.c: Define `WIN32_LEAN_AND_MEAN` before <windows.h>. libgomp/ PR middle-end/108300 * config/mingw32/proc.c: Define `WIN32_LEAN_AND_MEAN` before <windows.h>. libiberty/ PR middle-end/108300 * make-temp-file.c: Define `WIN32_LEAN_AND_MEAN` before <windows.h>. * pex-win32.c: Likewise. libssp/ PR middle-end/108300 * ssp.c: Define `WIN32_LEAN_AND_MEAN` before <windows.h>. libstdc++-v3/ PR middle-end/108300 * src/c++11/system_error.cc: Define `WIN32_LEAN_AND_MEAN` before <windows.h>. * src/c++11/thread.cc: Likewise. * src/c++17/fs_ops.cc: Likewise. * src/filesystem/ops.cc: Likewise. libvtv/ PR middle-end/108300 * vtv_malloc.cc: Define `WIN32_LEAN_AND_MEAN` before <windows.h>. * vtv_rts.cc: Likewise. * vtv_utils.cc: Likewise.
204 lines
5.4 KiB
C
204 lines
5.4 KiB
C
/* Stack protector support.
|
|
Copyright (C) 2005-2022 Free Software Foundation, Inc.
|
|
|
|
This file is part of GCC.
|
|
|
|
GCC is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free
|
|
Software Foundation; either version 3, or (at your option) any later
|
|
version.
|
|
|
|
In addition to the permissions in the GNU General Public License, the
|
|
Free Software Foundation gives you unlimited permission to link the
|
|
compiled version of this file into combinations with other programs,
|
|
and to distribute those combinations without any restriction coming
|
|
from the use of this file. (The General Public License restrictions
|
|
do apply in other respects; for example, they cover modification of
|
|
the file, and distribution when not linked into a combine
|
|
executable.)
|
|
|
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
for more details.
|
|
|
|
Under Section 7 of GPL version 3, you are granted additional
|
|
permissions described in the GCC Runtime Library Exception, version
|
|
3.1, as published by the Free Software Foundation.
|
|
|
|
You should have received a copy of the GNU General Public License and
|
|
a copy of the GCC Runtime Library Exception along with this program;
|
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
|
|
#include "config.h"
|
|
#ifdef HAVE_ALLOCA_H
|
|
# include <alloca.h>
|
|
#endif
|
|
#ifdef HAVE_MALLOC_H
|
|
# include <malloc.h>
|
|
#endif
|
|
#ifdef HAVE_STRING_H
|
|
# include <string.h>
|
|
#endif
|
|
#ifdef HAVE_UNISTD_H
|
|
# include <unistd.h>
|
|
#endif
|
|
#ifdef HAVE_FCNTL_H
|
|
# include <fcntl.h>
|
|
#endif
|
|
#ifdef HAVE_PATHS_H
|
|
# include <paths.h>
|
|
#endif
|
|
#ifndef _PATH_TTY
|
|
/* Native win32 apps don't know about /dev/tty but can print directly
|
|
to the console using "CONOUT$" */
|
|
#if defined (_WIN32) && !defined (__CYGWIN__)
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#include <wincrypt.h>
|
|
# define _PATH_TTY "CONOUT$"
|
|
#else
|
|
# define _PATH_TTY "/dev/tty"
|
|
#endif
|
|
#endif
|
|
#ifdef HAVE_SYSLOG_H
|
|
# include <syslog.h>
|
|
#endif
|
|
|
|
void *__stack_chk_guard = 0;
|
|
|
|
static void __attribute__ ((constructor))
|
|
__guard_setup (void)
|
|
{
|
|
unsigned char *p;
|
|
|
|
if (__stack_chk_guard != 0)
|
|
return;
|
|
|
|
#if defined (_WIN32) && !defined (__CYGWIN__)
|
|
HCRYPTPROV hprovider = 0;
|
|
if (CryptAcquireContext(&hprovider, NULL, NULL, PROV_RSA_FULL,
|
|
CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
|
|
{
|
|
if (CryptGenRandom(hprovider, sizeof (__stack_chk_guard),
|
|
(BYTE *)&__stack_chk_guard) && __stack_chk_guard != 0)
|
|
{
|
|
CryptReleaseContext(hprovider, 0);
|
|
return;
|
|
}
|
|
CryptReleaseContext(hprovider, 0);
|
|
}
|
|
#else
|
|
int fd = open ("/dev/urandom", O_RDONLY);
|
|
if (fd != -1)
|
|
{
|
|
ssize_t size = read (fd, &__stack_chk_guard,
|
|
sizeof (__stack_chk_guard));
|
|
close (fd);
|
|
if (size == sizeof(__stack_chk_guard) && __stack_chk_guard != 0)
|
|
return;
|
|
}
|
|
|
|
#endif
|
|
/* If a random generator can't be used, the protector switches the guard
|
|
to the "terminator canary". */
|
|
p = (unsigned char *) &__stack_chk_guard;
|
|
p[sizeof(__stack_chk_guard)-1] = 255;
|
|
p[sizeof(__stack_chk_guard)-2] = '\n';
|
|
p[0] = 0;
|
|
}
|
|
|
|
static void
|
|
fail (const char *msg1, size_t msg1len, const char *msg3)
|
|
{
|
|
#ifdef __GNU_LIBRARY__
|
|
extern char * __progname;
|
|
#else
|
|
static const char __progname[] = "";
|
|
#endif
|
|
int fd;
|
|
|
|
/* Print error message directly to the tty. This avoids Bad Things
|
|
happening if stderr is redirected. */
|
|
fd = open (_PATH_TTY, O_WRONLY);
|
|
if (fd != -1)
|
|
{
|
|
static const char msg2[] = " terminated\n";
|
|
size_t progname_len, len;
|
|
char *buf, *p;
|
|
|
|
progname_len = strlen (__progname);
|
|
len = msg1len + progname_len + sizeof(msg2)-1 + 1;
|
|
p = buf = alloca (len);
|
|
|
|
memcpy (p, msg1, msg1len);
|
|
p += msg1len;
|
|
memcpy (p, __progname, progname_len);
|
|
p += progname_len;
|
|
memcpy (p, msg2, sizeof(msg2));
|
|
|
|
while (len > 0)
|
|
{
|
|
ssize_t wrote = write (fd, buf, len);
|
|
if (wrote < 0)
|
|
break;
|
|
buf += wrote;
|
|
len -= wrote;
|
|
}
|
|
close (fd);
|
|
}
|
|
|
|
#ifdef HAVE_SYSLOG_H
|
|
/* Only send the error to syslog if there was no tty available. */
|
|
else
|
|
syslog (LOG_CRIT, "%s", msg3);
|
|
#endif /* HAVE_SYSLOG_H */
|
|
|
|
/* Try very hard to exit. Note that signals may be blocked preventing
|
|
the first two options from working. The use of volatile is here to
|
|
prevent optimizers from "knowing" that __builtin_trap is called first,
|
|
and that it doesn't return, and so "obviously" the rest of the code
|
|
is dead. */
|
|
{
|
|
volatile int state;
|
|
for (state = 0; ; state++)
|
|
switch (state)
|
|
{
|
|
case 0:
|
|
__builtin_trap ();
|
|
break;
|
|
case 1:
|
|
*(volatile int *)-1L = 0;
|
|
break;
|
|
case 2:
|
|
_exit (127);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
__stack_chk_fail (void)
|
|
{
|
|
const char *msg = "*** stack smashing detected ***: ";
|
|
fail (msg, strlen (msg), "stack smashing detected: terminated");
|
|
}
|
|
|
|
void
|
|
__chk_fail (void)
|
|
{
|
|
const char *msg = "*** buffer overflow detected ***: ";
|
|
fail (msg, strlen (msg), "buffer overflow detected: terminated");
|
|
}
|
|
|
|
#ifdef HAVE_HIDDEN_VISIBILITY
|
|
void
|
|
__attribute__((visibility ("hidden")))
|
|
__stack_chk_fail_local (void)
|
|
{
|
|
__stack_chk_fail ();
|
|
}
|
|
#endif
|