glibc's closefrom implementation does not work in a chroot when the kernel
does not have close_range. It tries to read from /proc/self/fd and when
that fails dies with an assertion of sorts. Instead, call close_range
ourselves from our compat code and fall back if that fails. bz#3349,
with william.wilson at canonical.com and fweimer at redhat.com.
dnl Target SUSv3/POSIX.1-2001 plus BSD specifics.
dnl _DEFAULT_SOURCE is the new name for _BSD_SOURCE
CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE"
+ AC_DEFINE([BROKEN_CLOSEFROM], [1], [broken in chroots on older kernels])
AC_DEFINE([PAM_TTY_KLUDGE], [1],
[Work around problematic Linux PAM modules handling of PAM_TTY])
AC_DEFINE([LOCKED_PASSWD_PREFIX], ["!"],
cap_rights_limit \
clock \
closefrom \
+ close_range \
dirfd \
endgrent \
err \
#include "includes.h"
-#ifndef HAVE_CLOSEFROM
+#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM)
#include <sys/types.h>
#include <sys/param.h>
DIR *dirp;
int len;
+#ifdef HAVE_CLOSE_RANGE
+ if (close_range(lowfd, INT_MAX, 0) == 0)
+ return;
+#endif
+
/* Check for a /proc/$$/fd directory. */
len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid());
if (len > 0 && (size_t)len < sizeof(fdpath) && (dirp = opendir(fdpath))) {