summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/rtld.c
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2005-03-24 10:12:29 +0000
committercperciva <cperciva@FreeBSD.org>2005-03-24 10:12:29 +0000
commitfdbab8722b21862ef5f520c8a54244f401b6a942 (patch)
tree63cf52526789317e12a6acb00010a992d75a8cf8 /libexec/rtld-elf/rtld.c
parente8e02448a84a6a804b73af267727bd34e16255d6 (diff)
downloadFreeBSD-src-fdbab8722b21862ef5f520c8a54244f401b6a942.zip
FreeBSD-src-fdbab8722b21862ef5f520c8a54244f401b6a942.tar.gz
If "dangerous" environment variables (LD_PRELOAD, LD_LIBMAP,
LD_LIBMAP_DISABLE, LD_LIBRARY_PATH) are used, then make sure the libraries being loaded aren't on a noexec-mounted filesystem. This is a compromise position: I'm assuming that nobody will be silly enough to set the noexec mount flag on part of the default library path, in order to avoid adding extra overhead into the common case (where those environment variables aren't used). Discussed with: csjp, secteam MFC after: 1 week
Diffstat (limited to 'libexec/rtld-elf/rtld.c')
-rw-r--r--libexec/rtld-elf/rtld.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 79d06ba..584576d 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -37,6 +37,7 @@
#endif
#include <sys/param.h>
+#include <sys/mount.h>
#include <sys/mman.h>
#include <sys/stat.h>
@@ -139,6 +140,8 @@ struct r_debug r_debug; /* for GDB; */
static bool libmap_disable; /* Disable libmap */
static char *libmap_override; /* Maps to use in addition to libmap.conf */
static bool trust; /* False for setuid and setgid programs */
+static bool dangerous_ld_env; /* True if environment variables have been
+ used to affect the libraries loaded */
static char *ld_bind_now; /* Environment variable for immediate binding */
static char *ld_debug; /* Environment variable for debugging */
static char *ld_library_path; /* Environment variable for search path */
@@ -293,7 +296,10 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
libmap_override = getenv(LD_ "LIBMAP");
ld_library_path = getenv(LD_ "LIBRARY_PATH");
ld_preload = getenv(LD_ "PRELOAD");
- }
+ dangerous_ld_env = libmap_disable || (libmap_override != NULL) ||
+ (ld_library_path != NULL) || (ld_preload != NULL);
+ } else
+ dangerous_ld_env = 0;
ld_tracing = getenv(LD_ "TRACE_LOADED_OBJECTS");
if (ld_debug != NULL && *ld_debug != '\0')
@@ -1218,6 +1224,7 @@ load_object(char *path)
Obj_Entry *obj;
int fd = -1;
struct stat sb;
+ struct statfs fs;
for (obj = obj_list->next; obj != NULL; obj = obj->next)
if (strcmp(obj->path, path) == 0)
@@ -1250,6 +1257,22 @@ load_object(char *path)
}
if (obj == NULL) { /* First use of this object, so we must map it in */
+ /*
+ * but first, make sure that environment variables haven't been
+ * used to circumvent the noexec flag on a filesystem.
+ */
+ if (dangerous_ld_env) {
+ if (fstatfs(fd, &fs) != 0) {
+ _rtld_error("Cannot fstatfs \"%s\"", path);
+ close(fd);
+ return NULL;
+ }
+ if (fs.f_flags & MNT_NOEXEC) {
+ _rtld_error("Cannot execute objects on %s\n", fs.f_mntonname);
+ close(fd);
+ return NULL;
+ }
+ }
dbg("loading \"%s\"", path);
obj = map_object(fd, path, &sb);
close(fd);
OpenPOWER on IntegriCloud