mirror of
https://git.savannah.gnu.org/git/gnulib.git
synced 2025-08-08 17:22:05 +03:00
c-stack: improve checking if !libsigsegv
If SIGINFO_WORKS, do not treat a null pointer dereference as if it were a stack overflow. Use uintptr_t and INT_ADD_WRAPV to avoid unlikely pointer overflow. Also, fix some obsolete code and typos. I found these problems while looking into this bug report: https://lists.gnu.org/r/grep-devel/2020-09/msg00053.html * lib/c-stack.c: Include c-stack.h first, to test interface. Include inttypes.h for UINTPTR_MAX, stdbool.h, stddef.h for max_align_t, intprops.h for INT_ADD_WRAPV. (USE_LIBSIGSEGV): New macro; use it to simplify later code. (SIGSTKSZ): Simplify setup. Work around libsigsegv bug only for libsigsegv 2.8 and earlier since the bug should be fixed after that. (alternate_signal_stack): Use max_align_t instead of doing it by hand. (segv_handler, overflow_handler, segv_handler) [DEBUG]: Assume sprintf returns byte count; this assumption is safe now. (page_size): New static volatile variable, since sysconf isn’t documented to be async-signal-safe on Solaris. This variable is present and used if (!USE_LIBSIGSEGV && HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK && HAVE_STACK_OVERFLOW_HANDLING && SIGINFO_WORKS). (segv_handler): Use it if present. Never report null pointer dereference as a stack overflow. Check for (unlikely) unsigned and/or pointer overflow. * m4/c-stack.m4 (AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC): Rename cache variables to gl_cv_sys_stack_overflow_works and gl_cv_sys_xsi_stack_overflow_heuristic. All uses changed. (gl_PREREQ_C_STACK): Do not require AC_FUNC_ALLOCA, since c-stack no longer uses STACK_DIRECTION. Do not check for unistd.h, since we depend on unistd. Fix shell typo ‘$"ac_cv_sys_xsi_stack_overflow_heuristic"’. * modules/c-stack (Depends-on): Sort. Add intprops, inttypes, stdbool, stddef.
This commit is contained in:
37
ChangeLog
37
ChangeLog
@@ -1,3 +1,40 @@
|
||||
2020-09-20 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
c-stack: improve checking if !libsigsegv
|
||||
If SIGINFO_WORKS, do not treat a null pointer dereference as if it
|
||||
were a stack overflow. Use uintptr_t and INT_ADD_WRAPV to avoid
|
||||
unlikely pointer overflow. Also, fix some obsolete code and typos.
|
||||
I found these problems while looking into this bug report:
|
||||
https://lists.gnu.org/r/grep-devel/2020-09/msg00053.html
|
||||
* lib/c-stack.c: Include c-stack.h first, to test interface.
|
||||
Include inttypes.h for UINTPTR_MAX, stdbool.h, stddef.h for
|
||||
max_align_t, intprops.h for INT_ADD_WRAPV.
|
||||
(USE_LIBSIGSEGV): New macro; use it to simplify later code.
|
||||
(SIGSTKSZ): Simplify setup. Work around libsigsegv bug only
|
||||
for libsigsegv 2.8 and earlier since the bug should be fixed
|
||||
after that.
|
||||
(alternate_signal_stack): Use max_align_t instead of doing it by hand.
|
||||
(segv_handler, overflow_handler, segv_handler) [DEBUG]:
|
||||
Assume sprintf returns byte count; this assumption is safe now.
|
||||
(page_size): New static volatile variable, since sysconf isn’t
|
||||
documented to be async-signal-safe on Solaris. This variable is
|
||||
present and used if (!USE_LIBSIGSEGV && HAVE_SIGALTSTACK &&
|
||||
HAVE_DECL_SIGALTSTACK && HAVE_STACK_OVERFLOW_HANDLING &&
|
||||
SIGINFO_WORKS).
|
||||
(segv_handler): Use it if present. Never report null pointer
|
||||
dereference as a stack overflow. Check for (unlikely) unsigned
|
||||
and/or pointer overflow.
|
||||
* m4/c-stack.m4 (AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC):
|
||||
Rename cache variables to gl_cv_sys_stack_overflow_works
|
||||
and gl_cv_sys_xsi_stack_overflow_heuristic.
|
||||
All uses changed.
|
||||
(gl_PREREQ_C_STACK): Do not require AC_FUNC_ALLOCA, since
|
||||
c-stack no longer uses STACK_DIRECTION.
|
||||
Do not check for unistd.h, since we depend on unistd.
|
||||
Fix shell typo ‘$"ac_cv_sys_xsi_stack_overflow_heuristic"’.
|
||||
* modules/c-stack (Depends-on): Sort. Add intprops, inttypes,
|
||||
stdbool, stddef.
|
||||
|
||||
2020-09-20 Bruno Haible <bruno@clisp.org>
|
||||
|
||||
Revert now-unnecessary override of config.guess on Alpine Linux 3.10.
|
||||
|
131
lib/c-stack.c
131
lib/c-stack.c
@@ -35,30 +35,25 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "c-stack.h"
|
||||
|
||||
#include "gettext.h"
|
||||
#define _(msgid) gettext (msgid)
|
||||
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <signal.h>
|
||||
#if ! HAVE_STACK_T && ! defined stack_t
|
||||
typedef struct sigaltstack stack_t;
|
||||
#endif
|
||||
#ifndef SIGSTKSZ
|
||||
# define SIGSTKSZ 16384
|
||||
#elif HAVE_LIBSIGSEGV && SIGSTKSZ < 16384
|
||||
/* libsigsegv 2.6 through 2.8 have a bug where some architectures use
|
||||
more than the Linux default of an 8k alternate stack when deciding
|
||||
if a fault was caused by stack overflow. */
|
||||
# undef SIGSTKSZ
|
||||
# define SIGSTKSZ 16384
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Posix 2001 declares ucontext_t in <ucontext.h>, Posix 200x in
|
||||
<signal.h>. */
|
||||
/* Pre-2008 POSIX declared ucontext_t in ucontext.h instead of signal.h. */
|
||||
#if HAVE_UCONTEXT_H
|
||||
# include <ucontext.h>
|
||||
#endif
|
||||
@@ -69,13 +64,26 @@ typedef struct sigaltstack stack_t;
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_LIBSIGSEGV
|
||||
/* Use libsigsegv only if needed; kernels like Solaris can detect
|
||||
stack overflow without the overhead of an external library. */
|
||||
#define USE_LIBSIGSEGV (HAVE_XSI_STACK_OVERFLOW_HEURISTIC && HAVE_LIBSIGSEGV)
|
||||
|
||||
#if USE_LIBSIGSEGV
|
||||
# include <sigsegv.h>
|
||||
/* libsigsegv 2.6 through 2.8 have a bug where some architectures use
|
||||
more than the Linux default of an 8k alternate stack when deciding
|
||||
if a fault was caused by stack overflow. */
|
||||
# if LIBSIGSEGV_VERSION <= 0x0208 && SIGSTKSZ < 16384
|
||||
# undef SIGSTKSZ
|
||||
# endif
|
||||
#endif
|
||||
#ifndef SIGSTKSZ
|
||||
# define SIGSTKSZ 16384
|
||||
#endif
|
||||
|
||||
#include "c-stack.h"
|
||||
#include "exitfail.h"
|
||||
#include "ignore-value.h"
|
||||
#include "intprops.h"
|
||||
#include "getprogname.h"
|
||||
|
||||
#if defined SA_ONSTACK && defined SA_SIGINFO
|
||||
@@ -97,7 +105,7 @@ static _GL_ASYNC_SAFE void (* volatile segv_action) (int);
|
||||
static char const * volatile program_error_message;
|
||||
static char const * volatile stack_overflow_message;
|
||||
|
||||
#if ((HAVE_LIBSIGSEGV && ! HAVE_XSI_STACK_OVERFLOW_HEURISTIC) \
|
||||
#if (USE_LIBSIGSEGV \
|
||||
|| (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK \
|
||||
&& HAVE_STACK_OVERFLOW_HANDLING))
|
||||
|
||||
@@ -111,12 +119,12 @@ static _GL_ASYNC_SAFE _Noreturn void
|
||||
die (int signo)
|
||||
{
|
||||
char const *message;
|
||||
#if !SIGINFO_WORKS && !HAVE_LIBSIGSEGV
|
||||
# if !SIGINFO_WORKS && !USE_LIBSIGSEGV
|
||||
/* We can't easily determine whether it is a stack overflow; so
|
||||
assume that the rest of our program is perfect (!) and that
|
||||
this segmentation violation is a stack overflow. */
|
||||
signo = 0;
|
||||
#endif /* !SIGINFO_WORKS && !HAVE_LIBSIGSEGV */
|
||||
# endif
|
||||
segv_action (signo);
|
||||
message = signo ? program_error_message : stack_overflow_message;
|
||||
ignore_value (write (STDERR_FILENO, progname, strlen (progname)));
|
||||
@@ -128,22 +136,12 @@ die (int signo)
|
||||
raise (signo);
|
||||
abort ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK \
|
||||
&& HAVE_STACK_OVERFLOW_HANDLING) || HAVE_LIBSIGSEGV
|
||||
|
||||
/* Storage for the alternate signal stack. */
|
||||
static union
|
||||
{
|
||||
char buffer[SIGSTKSZ];
|
||||
|
||||
/* These other members are for proper alignment. There's no
|
||||
standard way to guarantee stack alignment, but this seems enough
|
||||
in practice. */
|
||||
long double ld;
|
||||
long l;
|
||||
void *p;
|
||||
max_align_t align;
|
||||
} alternate_signal_stack;
|
||||
|
||||
static _GL_ASYNC_SAFE void
|
||||
@@ -153,10 +151,7 @@ null_action (int signo _GL_UNUSED)
|
||||
|
||||
#endif /* SIGALTSTACK || LIBSIGSEGV */
|
||||
|
||||
/* Only use libsigsegv if we need it; platforms like Solaris can
|
||||
detect stack overflow without the overhead of an external
|
||||
library. */
|
||||
#if HAVE_LIBSIGSEGV && ! HAVE_XSI_STACK_OVERFLOW_HEURISTIC
|
||||
#if USE_LIBSIGSEGV
|
||||
|
||||
/* Nonzero if general segv handler could not be installed. */
|
||||
static volatile int segv_handler_missing;
|
||||
@@ -171,8 +166,8 @@ segv_handler (void *address _GL_UNUSED, int serious)
|
||||
{
|
||||
char buf[1024];
|
||||
int saved_errno = errno;
|
||||
sprintf (buf, "segv_handler serious=%d\n", serious);
|
||||
ignore_value (write (STDERR_FILENO, buf, strlen (buf)));
|
||||
ignore_value (write (STDERR_FILENO, buf,
|
||||
sprintf (buf, "segv_handler serious=%d\n", serious)));
|
||||
errno = saved_errno;
|
||||
}
|
||||
# endif
|
||||
@@ -193,9 +188,10 @@ overflow_handler (int emergency, stackoverflow_context_t context _GL_UNUSED)
|
||||
# if DEBUG
|
||||
{
|
||||
char buf[1024];
|
||||
sprintf (buf, "overflow_handler emergency=%d segv_handler_missing=%d\n",
|
||||
emergency, segv_handler_missing);
|
||||
ignore_value (write (STDERR_FILENO, buf, strlen (buf)));
|
||||
ignore_value (write (STDERR_FILENO, buf,
|
||||
sprintf (buf, ("overflow_handler emergency=%d"
|
||||
" segv_handler_missing=%d\n"),
|
||||
emergency, segv_handler_missing)));
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -228,6 +224,8 @@ c_stack_action (_GL_ASYNC_SAFE void (*action) (int))
|
||||
|
||||
# if SIGINFO_WORKS
|
||||
|
||||
static size_t volatile page_size;
|
||||
|
||||
/* Handle a segmentation violation and exit. This function is
|
||||
async-signal-safe. */
|
||||
|
||||
@@ -235,8 +233,17 @@ static _GL_ASYNC_SAFE _Noreturn void
|
||||
segv_handler (int signo, siginfo_t *info, void *context _GL_UNUSED)
|
||||
{
|
||||
/* Clear SIGNO if it seems to have been a stack overflow. */
|
||||
# if ! HAVE_XSI_STACK_OVERFLOW_HEURISTIC
|
||||
/* We can't easily determine whether it is a stack overflow; so
|
||||
|
||||
/* If si_code is nonpositive, something like raise (SIGSEGV) occurred
|
||||
so it cannot be a stack overflow. */
|
||||
bool cannot_be_stack_overflow = info->si_code <= 0;
|
||||
|
||||
/* An unaligned address cannot be a stack overflow. */
|
||||
# if FAULT_YIELDS_SIGBUS
|
||||
cannot_be_stack_overflow |= signo == SIGBUS && info->si_code == BUS_ADRALN;
|
||||
# endif
|
||||
|
||||
/* If we can't easily determine that it is not a stack overflow,
|
||||
assume that the rest of our program is perfect (!) and that
|
||||
this segmentation violation is a stack overflow.
|
||||
|
||||
@@ -246,33 +253,44 @@ segv_handler (int signo, siginfo_t *info, void *context _GL_UNUSED)
|
||||
Solaris populates uc_stack with the details of the
|
||||
interrupted stack, while Linux populates it with the details
|
||||
of the current stack. */
|
||||
signo = 0;
|
||||
# else
|
||||
if (0 < info->si_code)
|
||||
if (!cannot_be_stack_overflow)
|
||||
{
|
||||
/* If the faulting address is within the stack, or within one
|
||||
page of the stack, assume that it is a stack overflow. */
|
||||
uintptr_t faulting_address = (uintptr_t) info->si_addr;
|
||||
|
||||
/* On all platforms we know of, the first page is not in the
|
||||
stack to catch null pointer dereferening. However, all other
|
||||
pages might be in the stack. */
|
||||
void *stack_base = (void *) (uintptr_t) page_size;
|
||||
uintptr_t stack_size = 0; stack_size -= page_size;
|
||||
# if HAVE_XSI_STACK_OVERFLOW_HEURISTIC
|
||||
/* Tighten the stack bounds via the XSI heuristic. */
|
||||
ucontext_t const *user_context = context;
|
||||
char const *stack_base = user_context->uc_stack.ss_sp;
|
||||
size_t stack_size = user_context->uc_stack.ss_size;
|
||||
char const *faulting_address = info->si_addr;
|
||||
size_t page_size = sysconf (_SC_PAGESIZE);
|
||||
size_t s = faulting_address - stack_base + page_size;
|
||||
if (s < stack_size + 2 * page_size)
|
||||
stack_base = user_context->uc_stack.ss_sp;
|
||||
stack_size = user_context->uc_stack.ss_size;
|
||||
# endif
|
||||
uintptr_t base = (uintptr_t) stack_base,
|
||||
lo = (INT_SUBTRACT_WRAPV (base, page_size, &lo) || lo < page_size
|
||||
? page_size : lo),
|
||||
hi = ((INT_ADD_WRAPV (base, stack_size, &hi)
|
||||
|| INT_ADD_WRAPV (hi, page_size - 1, &hi))
|
||||
? UINTPTR_MAX : hi);
|
||||
if (lo <= faulting_address && faulting_address <= hi)
|
||||
signo = 0;
|
||||
|
||||
# if DEBUG
|
||||
{
|
||||
char buf[1024];
|
||||
ignore_value (write (STDERR_FILENO, buf,
|
||||
sprintf (buf,
|
||||
"segv_handler fault=%p base=%p size=%lx page=%lx signo=%d\n",
|
||||
faulting_address, stack_base, (unsigned long) stack_size,
|
||||
(unsigned long) page_size, signo);
|
||||
ignore_value (write (STDERR_FILENO, buf, strlen (buf)));
|
||||
("segv_handler code=%d fault=%p base=%p"
|
||||
" size=0x%zx page=0x%zx signo=%d\n"),
|
||||
info->si_code, info->si_addr, stack_base,
|
||||
stack_size, page_size, signo)));
|
||||
}
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
|
||||
die (signo);
|
||||
}
|
||||
@@ -303,6 +321,10 @@ c_stack_action (_GL_ASYNC_SAFE void (*action) (int))
|
||||
stack_overflow_message = _("stack overflow");
|
||||
progname = getprogname ();
|
||||
|
||||
# if SIGINFO_WORKS
|
||||
page_size = sysconf (_SC_PAGESIZE);
|
||||
# endif
|
||||
|
||||
sigemptyset (&act.sa_mask);
|
||||
|
||||
# if SIGINFO_WORKS
|
||||
@@ -323,8 +345,9 @@ c_stack_action (_GL_ASYNC_SAFE void (*action) (int))
|
||||
return sigaction (SIGSEGV, &act, NULL);
|
||||
}
|
||||
|
||||
#else /* ! ((HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK
|
||||
&& HAVE_STACK_OVERFLOW_HANDLING) || HAVE_LIBSIGSEGV) */
|
||||
#else /* ! (USE_LIBSIGSEGV
|
||||
|| (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK
|
||||
&& HAVE_STACK_OVERFLOW_HANDLING)) */
|
||||
|
||||
int
|
||||
c_stack_action (_GL_ASYNC_SAFE void (*action) (int) _GL_UNUSED)
|
||||
|
@@ -7,7 +7,7 @@
|
||||
|
||||
# Written by Paul Eggert.
|
||||
|
||||
# serial 17
|
||||
# serial 18
|
||||
|
||||
AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC],
|
||||
[
|
||||
@@ -34,7 +34,7 @@ AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC],
|
||||
[Define to 1 if an invalid memory address access may yield a SIGBUS.])
|
||||
|
||||
AC_CACHE_CHECK([for working C stack overflow detection],
|
||||
[ac_cv_sys_stack_overflow_works],
|
||||
[gl_cv_sys_stack_overflow_works],
|
||||
[AC_RUN_IFELSE([AC_LANG_SOURCE(
|
||||
[[
|
||||
#include <unistd.h>
|
||||
@@ -121,17 +121,17 @@ AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC],
|
||||
return recurse (0);
|
||||
}
|
||||
]])],
|
||||
[ac_cv_sys_stack_overflow_works=yes],
|
||||
[ac_cv_sys_stack_overflow_works=no],
|
||||
[gl_cv_sys_stack_overflow_works=yes],
|
||||
[gl_cv_sys_stack_overflow_works=no],
|
||||
[case "$host_os" in
|
||||
# Guess no on native Windows.
|
||||
mingw*) ac_cv_sys_stack_overflow_works="guessing no" ;;
|
||||
*) ac_cv_sys_stack_overflow_works=cross-compiling ;;
|
||||
mingw*) gl_cv_sys_stack_overflow_works="guessing no" ;;
|
||||
*) gl_cv_sys_stack_overflow_works=cross-compiling ;;
|
||||
esac
|
||||
])
|
||||
])
|
||||
|
||||
if test "$ac_cv_sys_stack_overflow_works" = yes; then
|
||||
if test "$gl_cv_sys_stack_overflow_works" = yes; then
|
||||
AC_DEFINE([HAVE_STACK_OVERFLOW_HANDLING], [1],
|
||||
[Define to 1 if extending the stack slightly past the limit causes
|
||||
a SIGSEGV which can be handled on an alternate stack established
|
||||
@@ -200,14 +200,14 @@ int main ()
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for precise C stack overflow detection],
|
||||
[ac_cv_sys_xsi_stack_overflow_heuristic],
|
||||
[gl_cv_sys_xsi_stack_overflow_heuristic],
|
||||
[dnl On Linux/sparc64 (both in 32-bit and 64-bit mode), it would be wrong
|
||||
dnl to set HAVE_XSI_STACK_OVERFLOW_HEURISTIC to 1, because the third
|
||||
dnl argument passed to the segv_handler is a 'struct sigcontext *', not
|
||||
dnl an 'ucontext_t *'. It would lead to a failure of test-c-stack2.sh.
|
||||
case "${host_os}--${host_cpu}" in
|
||||
linux*--sparc*)
|
||||
ac_cv_sys_xsi_stack_overflow_heuristic=no
|
||||
gl_cv_sys_xsi_stack_overflow_heuristic=no
|
||||
;;
|
||||
*)
|
||||
AC_RUN_IFELSE(
|
||||
@@ -329,14 +329,14 @@ int main ()
|
||||
return recurse (0);
|
||||
}
|
||||
]])],
|
||||
[ac_cv_sys_xsi_stack_overflow_heuristic=yes],
|
||||
[ac_cv_sys_xsi_stack_overflow_heuristic=no],
|
||||
[ac_cv_sys_xsi_stack_overflow_heuristic=cross-compiling])
|
||||
[gl_cv_sys_xsi_stack_overflow_heuristic=yes],
|
||||
[gl_cv_sys_xsi_stack_overflow_heuristic=no],
|
||||
[gl_cv_sys_xsi_stack_overflow_heuristic=cross-compiling])
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
||||
if test $ac_cv_sys_xsi_stack_overflow_heuristic = yes; then
|
||||
if test "$gl_cv_sys_xsi_stack_overflow_heuristic" = yes; then
|
||||
AC_DEFINE([HAVE_XSI_STACK_OVERFLOW_HEURISTIC], [1],
|
||||
[Define to 1 if extending the stack slightly past the limit causes
|
||||
a SIGSEGV, and an alternate stack can be established with sigaltstack,
|
||||
@@ -353,19 +353,16 @@ AC_DEFUN([gl_PREREQ_C_STACK],
|
||||
[AC_REQUIRE([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC])
|
||||
AC_REQUIRE([gl_LIBSIGSEGV])
|
||||
|
||||
# for STACK_DIRECTION
|
||||
AC_REQUIRE([AC_FUNC_ALLOCA])
|
||||
|
||||
AC_CHECK_FUNCS_ONCE([sigaltstack])
|
||||
AC_CHECK_DECLS([sigaltstack], , , [[#include <signal.h>]])
|
||||
|
||||
AC_CHECK_HEADERS_ONCE([unistd.h ucontext.h])
|
||||
AC_CHECK_HEADERS_ONCE([ucontext.h])
|
||||
|
||||
AC_CHECK_TYPES([stack_t], , , [#include <signal.h>])
|
||||
|
||||
dnl c-stack does not need -lsigsegv if the system has XSI heuristics.
|
||||
if test "$gl_cv_lib_sigsegv" = yes \
|
||||
&& test $"ac_cv_sys_xsi_stack_overflow_heuristic" != yes ; then
|
||||
&& test "$gl_cv_sys_xsi_stack_overflow_heuristic" != yes; then
|
||||
AC_SUBST([LIBCSTACK], [$LIBSIGSEGV])
|
||||
AC_SUBST([LTLIBCSTACK], [$LTLIBSIGSEGV])
|
||||
fi
|
||||
|
@@ -7,15 +7,19 @@ lib/c-stack.c
|
||||
m4/c-stack.m4
|
||||
|
||||
Depends-on:
|
||||
gettext-h
|
||||
errno
|
||||
exitfail
|
||||
getprogname
|
||||
gettext-h
|
||||
ignore-value
|
||||
unistd
|
||||
intprops
|
||||
inttypes
|
||||
libsigsegv
|
||||
raise
|
||||
sigaction
|
||||
libsigsegv
|
||||
getprogname
|
||||
stdbool
|
||||
stddef
|
||||
unistd
|
||||
|
||||
configure.ac:
|
||||
gl_C_STACK
|
||||
|
Reference in New Issue
Block a user