wok-current annotate glibc/stuff/glibc-2.23_ssp.patch @ rev 25775

Patch glibc (CVE-2025-4802)
author Stanislas Leduc <shann@slitaz.org>
date Thu May 22 19:19:31 2025 +0000 (5 months ago)
parents
children
rev   line source
shann@25634 1 diff --git a/debug/Makefile b/debug/Makefile
shann@25634 2 index 6b5f31e..535f10a 100644
shann@25634 3 --- a/debug/Makefile
shann@25634 4 +++ b/debug/Makefile
shann@25634 5 @@ -53,6 +53,7 @@ routines = backtrace backtracesyms backtracesymsfd noophooks \
shann@25634 6 static-only-routines := warning-nop stack_chk_fail_local
shann@25634 7
shann@25634 8 CFLAGS-backtrace.c = -fno-omit-frame-pointer
shann@25634 9 +CFLAGS-stack_chk_fail.c = -DSSP_SMASH_DUMPS_CORE
shann@25634 10 CFLAGS-sprintf_chk.c = $(libio-mtsafe)
shann@25634 11 CFLAGS-snprintf_chk.c = $(libio-mtsafe)
shann@25634 12 CFLAGS-vsprintf_chk.c = $(libio-mtsafe)
shann@25634 13 diff --git a/debug/stack_chk_fail.c b/debug/stack_chk_fail.c
shann@25634 14 index 4d0796f..c6ce7dc 100644
shann@25634 15 --- a/debug/stack_chk_fail.c
shann@25634 16 +++ b/debug/stack_chk_fail.c
shann@25634 17 @@ -15,15 +15,296 @@
shann@25634 18 License along with the GNU C Library; if not, see
shann@25634 19 <http://www.gnu.org/licenses/>. */
shann@25634 20
shann@25634 21 -#include <stdio.h>
shann@25634 22 +/* Copyright (C) 2006-2007 Gentoo Foundation Inc.
shann@25634 23 + * License terms as above.
shann@25634 24 + *
shann@25634 25 + * Hardened Gentoo SSP handler
shann@25634 26 + *
shann@25634 27 + * An SSP failure handler that does not use functions from the rest of
shann@25634 28 + * glibc; it uses the INTERNAL_SYSCALL methods directly. This ensures
shann@25634 29 + * no possibility of recursion into the handler.
shann@25634 30 + *
shann@25634 31 + * Direct all bug reports to http://bugs.gentoo.org/
shann@25634 32 + *
shann@25634 33 + * Re-written from the glibc-2.3 Hardened Gentoo SSP handler
shann@25634 34 + * by Kevin F. Quinn - <kevquinn[@]gentoo.org>
shann@25634 35 + *
shann@25634 36 + * The following people contributed to the glibc-2.3 Hardened
shann@25634 37 + * Gentoo SSP handler, from which this implementation draws much:
shann@25634 38 + *
shann@25634 39 + * Ned Ludd - <solar[@]gentoo.org>
shann@25634 40 + * Alexander Gabert - <pappy[@]gentoo.org>
shann@25634 41 + * The PaX Team - <pageexec[@]freemail.hu>
shann@25634 42 + * Peter S. Mazinger - <ps.m[@]gmx.net>
shann@25634 43 + * Yoann Vandoorselaere - <yoann[@]prelude-ids.org>
shann@25634 44 + * Robert Connolly - <robert[@]linuxfromscratch.org>
shann@25634 45 + * Cory Visi <cory[@]visi.name>
shann@25634 46 + * Mike Frysinger <vapier[@]gentoo.org>
shann@25634 47 + */
shann@25634 48 +
shann@25634 49 +#include <errno.h>
shann@25634 50 #include <stdlib.h>
shann@25634 51 +#include <unistd.h>
shann@25634 52 +#include <signal.h>
shann@25634 53 +
shann@25634 54 +#include <sys/types.h>
shann@25634 55 +
shann@25634 56 +#include <sysdep-cancel.h>
shann@25634 57 +#include <sys/syscall.h>
shann@25634 58 +
shann@25634 59 +#include <kernel-features.h>
shann@25634 60 +
shann@25634 61 +#include <alloca.h>
shann@25634 62 +/* from sysdeps */
shann@25634 63 +#include <socketcall.h>
shann@25634 64 +/* for the stuff in bits/socket.h */
shann@25634 65 +#include <sys/socket.h>
shann@25634 66 +#include <sys/un.h>
shann@25634 67 +
shann@25634 68 +
shann@25634 69 +/* Sanity check on SYSCALL macro names - force compilation
shann@25634 70 + * failure if the names used here do not exist
shann@25634 71 + */
shann@25634 72 +#if !defined __NR_socketcall && !defined __NR_socket
shann@25634 73 +# error Cannot do syscall socket or socketcall
shann@25634 74 +#endif
shann@25634 75 +#if !defined __NR_socketcall && !defined __NR_connect
shann@25634 76 +# error Cannot do syscall connect or socketcall
shann@25634 77 +#endif
shann@25634 78 +#ifndef __NR_write
shann@25634 79 +# error Cannot do syscall write
shann@25634 80 +#endif
shann@25634 81 +#ifndef __NR_close
shann@25634 82 +# error Cannot do syscall close
shann@25634 83 +#endif
shann@25634 84 +#ifndef __NR_getpid
shann@25634 85 +# error Cannot do syscall getpid
shann@25634 86 +#endif
shann@25634 87 +#ifndef __NR_kill
shann@25634 88 +# error Cannot do syscall kill
shann@25634 89 +#endif
shann@25634 90 +#ifndef __NR_exit
shann@25634 91 +# error Cannot do syscall exit
shann@25634 92 +#endif
shann@25634 93 +#ifdef SSP_SMASH_DUMPS_CORE
shann@25634 94 +# define ENABLE_SSP_SMASH_DUMPS_CORE 1
shann@25634 95 +# if !defined _KERNEL_NSIG && !defined _NSIG
shann@25634 96 +# error No _NSIG or _KERNEL_NSIG for rt_sigaction
shann@25634 97 +# endif
shann@25634 98 +# if !defined __NR_sigaction && !defined __NR_rt_sigaction
shann@25634 99 +# error Cannot do syscall sigaction or rt_sigaction
shann@25634 100 +# endif
shann@25634 101 +/* Although rt_sigaction expects sizeof(sigset_t) - it expects the size
shann@25634 102 + * of the _kernel_ sigset_t which is not the same as the user sigset_t.
shann@25634 103 + * Most arches have this as _NSIG bits - mips has _KERNEL_NSIG bits for
shann@25634 104 + * some reason.
shann@25634 105 + */
shann@25634 106 +# ifdef _KERNEL_NSIG
shann@25634 107 +# define _SSP_NSIG _KERNEL_NSIG
shann@25634 108 +# else
shann@25634 109 +# define _SSP_NSIG _NSIG
shann@25634 110 +# endif
shann@25634 111 +#else
shann@25634 112 +# define _SSP_NSIG 0
shann@25634 113 +# define ENABLE_SSP_SMASH_DUMPS_CORE 0
shann@25634 114 +#endif
shann@25634 115 +
shann@25634 116 +/* Define DO_SIGACTION - default to newer rt signal interface but
shann@25634 117 + * fallback to old as needed.
shann@25634 118 + */
shann@25634 119 +#ifdef __NR_rt_sigaction
shann@25634 120 +# define DO_SIGACTION(signum, act, oldact) \
shann@25634 121 + INLINE_SYSCALL(rt_sigaction, 4, signum, act, oldact, _SSP_NSIG/8)
shann@25634 122 +#else
shann@25634 123 +# define DO_SIGACTION(signum, act, oldact) \
shann@25634 124 + INLINE_SYSCALL(sigaction, 3, signum, act, oldact)
shann@25634 125 +#endif
shann@25634 126 +
shann@25634 127 +/* Define DO_SOCKET/DO_CONNECT functions to deal with socketcall vs socket/connect */
shann@25634 128 +#if defined(__NR_socket) && defined(__NR_connect)
shann@25634 129 +# define USE_OLD_SOCKETCALL 0
shann@25634 130 +#else
shann@25634 131 +# define USE_OLD_SOCKETCALL 1
shann@25634 132 +#endif
shann@25634 133 +/* stub out the __NR_'s so we can let gcc optimize away dead code */
shann@25634 134 +#ifndef __NR_socketcall
shann@25634 135 +# define __NR_socketcall 0
shann@25634 136 +#endif
shann@25634 137 +#ifndef __NR_socket
shann@25634 138 +# define __NR_socket 0
shann@25634 139 +#endif
shann@25634 140 +#ifndef __NR_connect
shann@25634 141 +# define __NR_connect 0
shann@25634 142 +#endif
shann@25634 143 +#define DO_SOCKET(result, domain, type, protocol) \
shann@25634 144 + do { \
shann@25634 145 + if (USE_OLD_SOCKETCALL) { \
shann@25634 146 + socketargs[0] = domain; \
shann@25634 147 + socketargs[1] = type; \
shann@25634 148 + socketargs[2] = protocol; \
shann@25634 149 + socketargs[3] = 0; \
shann@25634 150 + result = INLINE_SYSCALL(socketcall, 2, SOCKOP_socket, socketargs); \
shann@25634 151 + } else \
shann@25634 152 + result = INLINE_SYSCALL(socket, 3, domain, type, protocol); \
shann@25634 153 + } while (0)
shann@25634 154 +#define DO_CONNECT(result, sockfd, serv_addr, addrlen) \
shann@25634 155 + do { \
shann@25634 156 + if (USE_OLD_SOCKETCALL) { \
shann@25634 157 + socketargs[0] = sockfd; \
shann@25634 158 + socketargs[1] = (unsigned long int)serv_addr; \
shann@25634 159 + socketargs[2] = addrlen; \
shann@25634 160 + socketargs[3] = 0; \
shann@25634 161 + result = INLINE_SYSCALL(socketcall, 2, SOCKOP_connect, socketargs); \
shann@25634 162 + } else \
shann@25634 163 + result = INLINE_SYSCALL(connect, 3, sockfd, serv_addr, addrlen); \
shann@25634 164 + } while (0)
shann@25634 165 +
shann@25634 166 +#ifndef _PATH_LOG
shann@25634 167 +# define _PATH_LOG "/dev/log"
shann@25634 168 +#endif
shann@25634 169 +
shann@25634 170 +static const char path_log[] = _PATH_LOG;
shann@25634 171 +
shann@25634 172 +/* For building glibc with SSP switched on, define __progname to a
shann@25634 173 + * constant if building for the run-time loader, to avoid pulling
shann@25634 174 + * in more of libc.so into ld.so
shann@25634 175 + */
shann@25634 176 +#ifdef IS_IN_rtld
shann@25634 177 +static char *__progname = "<rtld>";
shann@25634 178 +#else
shann@25634 179 +extern char *__progname;
shann@25634 180 +#endif
shann@25634 181 +
shann@25634 182
shann@25634 183 +/* Common handler code, used by stack_chk_fail and __stack_smash_handler
shann@25634 184 + * Inlined to ensure no self-references to the handler within itself.
shann@25634 185 + * Data static to avoid putting more than necessary on the stack,
shann@25634 186 + * to aid core debugging.
shann@25634 187 + * The copy in rtld must be hidden to ensure that it gets no relocations
shann@25634 188 + * and thus does not crash if called during libc startup.
shann@25634 189 + */
shann@25634 190 +__attribute__ ((__noreturn__ , __always_inline__))
shann@25634 191 +#ifdef IS_IN_rtld
shann@25634 192 +attribute_hidden
shann@25634 193 +#endif
shann@25634 194 +static inline void
shann@25634 195 +__hardened_gentoo_stack_chk_fail(char func[], int damaged)
shann@25634 196 +{
shann@25634 197 +#define MESSAGE_BUFSIZ 256
shann@25634 198 + static pid_t pid;
shann@25634 199 + static int plen, i;
shann@25634 200 + static char message[MESSAGE_BUFSIZ];
shann@25634 201 + static const char msg_ssa[] = ": stack smashing attack";
shann@25634 202 + static const char msg_inf[] = " in function ";
shann@25634 203 + static const char msg_ssd[] = "*** stack smashing detected ***: ";
shann@25634 204 + static const char msg_terminated[] = " - terminated\n";
shann@25634 205 + static const char msg_unknown[] = "<unknown>";
shann@25634 206 + static int log_socket, connect_result;
shann@25634 207 + static struct sockaddr_un sock;
shann@25634 208 + static unsigned long int socketargs[4];
shann@25634 209 +
shann@25634 210 + /* Build socket address
shann@25634 211 + */
shann@25634 212 + sock.sun_family = AF_UNIX;
shann@25634 213 + i = 0;
shann@25634 214 + while ((path_log[i] != '\0') && (i<(sizeof(sock.sun_path)-1))) {
shann@25634 215 + sock.sun_path[i] = path_log[i];
shann@25634 216 + i++;
shann@25634 217 + }
shann@25634 218 + sock.sun_path[i] = '\0';
shann@25634 219 +
shann@25634 220 + /* Try SOCK_DGRAM connection to syslog */
shann@25634 221 + connect_result = -1;
shann@25634 222 + DO_SOCKET(log_socket, AF_UNIX, SOCK_DGRAM, 0);
shann@25634 223 + if (log_socket != -1)
shann@25634 224 + DO_CONNECT(connect_result, log_socket, &sock, sizeof(sock));
shann@25634 225 + if (connect_result == -1) {
shann@25634 226 + if (log_socket != -1)
shann@25634 227 + INLINE_SYSCALL(close, 1, log_socket);
shann@25634 228 + /* Try SOCK_STREAM connection to syslog */
shann@25634 229 + DO_SOCKET(log_socket, AF_UNIX, SOCK_STREAM, 0);
shann@25634 230 + if (log_socket != -1)
shann@25634 231 + DO_CONNECT(connect_result, log_socket, &sock, sizeof(sock));
shann@25634 232 + }
shann@25634 233 +
shann@25634 234 + /* Build message. Messages are generated both in the old style and new style,
shann@25634 235 + * so that log watchers that are configured for the old-style message continue
shann@25634 236 + * to work.
shann@25634 237 + */
shann@25634 238 +#define strconcat(str) \
shann@25634 239 + {i=0; while ((str[i] != '\0') && ((i+plen)<(MESSAGE_BUFSIZ-1))) \
shann@25634 240 + {\
shann@25634 241 + message[plen+i]=str[i];\
shann@25634 242 + i++;\
shann@25634 243 + }\
shann@25634 244 + plen+=i;}
shann@25634 245 +
shann@25634 246 + /* R.Henderson post-gcc-4 style message */
shann@25634 247 + plen = 0;
shann@25634 248 + strconcat(msg_ssd);
shann@25634 249 + if (__progname != (char *)0)
shann@25634 250 + strconcat(__progname)
shann@25634 251 + else
shann@25634 252 + strconcat(msg_unknown);
shann@25634 253 + strconcat(msg_terminated);
shann@25634 254 +
shann@25634 255 + /* Write out error message to STDERR, to syslog if open */
shann@25634 256 + INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
shann@25634 257 + if (connect_result != -1)
shann@25634 258 + INLINE_SYSCALL(write, 3, log_socket, message, plen);
shann@25634 259 +
shann@25634 260 + /* Dr. Etoh pre-gcc-4 style message */
shann@25634 261 + plen = 0;
shann@25634 262 + if (__progname != (char *)0)
shann@25634 263 + strconcat(__progname)
shann@25634 264 + else
shann@25634 265 + strconcat(msg_unknown);
shann@25634 266 + strconcat(msg_ssa);
shann@25634 267 + strconcat(msg_inf);
shann@25634 268 + if (func != NULL)
shann@25634 269 + strconcat(func)
shann@25634 270 + else
shann@25634 271 + strconcat(msg_unknown);
shann@25634 272 + strconcat(msg_terminated);
shann@25634 273 + /* Write out error message to STDERR, to syslog if open */
shann@25634 274 + INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
shann@25634 275 + if (connect_result != -1)
shann@25634 276 + INLINE_SYSCALL(write, 3, log_socket, message, plen);
shann@25634 277
shann@25634 278 -extern char **__libc_argv attribute_hidden;
shann@25634 279 + /* Write out error message to STDERR, to syslog if open */
shann@25634 280 + INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
shann@25634 281 + if (connect_result != -1)
shann@25634 282 + INLINE_SYSCALL(write, 3, log_socket, message, plen);
shann@25634 283 +
shann@25634 284 + if (log_socket != -1)
shann@25634 285 + INLINE_SYSCALL(close, 1, log_socket);
shann@25634 286 +
shann@25634 287 + /* Suicide */
shann@25634 288 + pid = INLINE_SYSCALL(getpid, 0);
shann@25634 289 +
shann@25634 290 + if (ENABLE_SSP_SMASH_DUMPS_CORE) {
shann@25634 291 + static struct sigaction default_abort_act;
shann@25634 292 + /* Remove any user-supplied handler for SIGABRT, before using it */
shann@25634 293 + default_abort_act.sa_handler = SIG_DFL;
shann@25634 294 + default_abort_act.sa_sigaction = NULL;
shann@25634 295 + __sigfillset(&default_abort_act.sa_mask);
shann@25634 296 + default_abort_act.sa_flags = 0;
shann@25634 297 + if (DO_SIGACTION(SIGABRT, &default_abort_act, NULL) == 0)
shann@25634 298 + INLINE_SYSCALL(kill, 2, pid, SIGABRT);
shann@25634 299 + }
shann@25634 300 +
shann@25634 301 + /* Note; actions cannot be added to SIGKILL */
shann@25634 302 + INLINE_SYSCALL(kill, 2, pid, SIGKILL);
shann@25634 303 +
shann@25634 304 + /* In case the kill didn't work, exit anyway
shann@25634 305 + * The loop prevents gcc thinking this routine returns
shann@25634 306 + */
shann@25634 307 + while (1)
shann@25634 308 + INLINE_SYSCALL(exit, 0);
shann@25634 309 +}
shann@25634 310
shann@25634 311 -void
shann@25634 312 -__attribute__ ((noreturn))
shann@25634 313 -__stack_chk_fail (void)
shann@25634 314 +__attribute__ ((__noreturn__))
shann@25634 315 +void __stack_chk_fail(void)
shann@25634 316 {
shann@25634 317 - __fortify_fail ("stack smashing detected");
shann@25634 318 + __hardened_gentoo_stack_chk_fail(NULL, 0);
shann@25634 319 }