summaryrefslogtreecommitdiff
path: root/openbsd-compat/bsd-closefrom.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@dtucker.net>2021-11-10 12:34:25 +1100
committerDarren Tucker <dtucker@dtucker.net>2021-11-10 12:34:25 +1100
commit10b899a15c88eb40eb5f73cd0fa84ef0966f79c9 (patch)
tree4f34af056504ed1e101f1fcbdd5eb919ce86b915 /openbsd-compat/bsd-closefrom.c
parenteb1f63195a9a38b519536a5b398d9939261ec081 (diff)
downloadopenssh-git-10b899a15c88eb40eb5f73cd0fa84ef0966f79c9.tar.gz
Don't trust closefrom() on Linux.
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.
Diffstat (limited to 'openbsd-compat/bsd-closefrom.c')
-rw-r--r--openbsd-compat/bsd-closefrom.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c
index 8fadca2d..08b7da69 100644
--- a/openbsd-compat/bsd-closefrom.c
+++ b/openbsd-compat/bsd-closefrom.c
@@ -16,7 +16,7 @@
#include "includes.h"
-#ifndef HAVE_CLOSEFROM
+#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM)
#include <sys/types.h>
#include <sys/param.h>
@@ -130,6 +130,11 @@ closefrom(int lowfd)
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))) {