diff --git a/sbin/ldconfig/elfhints.c b/sbin/ldconfig/elfhints.c index 6af39b655d2f..f7139dfcb0a0 100644 --- a/sbin/ldconfig/elfhints.c +++ b/sbin/ldconfig/elfhints.c @@ -57,7 +57,22 @@ static int ndirs; static void add_dir(const char *hintsfile, const char *name) { - int i; + struct stat stbuf; + int i; + + /* Do some security checks */ + if (stat(name, &stbuf) == -1) { + warn("%s", name); + return; + } + if (stbuf.st_uid != 0) { + warnx("%s: not owned by root", name); + return; + } + if ((stbuf.st_mode & S_IWOTH) != 0) { + warnx("%s: ignoring world-writable directory", name); + return; + } for (i = 0; i < ndirs; i++) if (strcmp(dirs[i], name) == 0) diff --git a/sbin/ldconfig/ldconfig.8 b/sbin/ldconfig/ldconfig.8 index 8f4f801b32ee..f008d90342a6 100644 --- a/sbin/ldconfig/ldconfig.8 +++ b/sbin/ldconfig/ldconfig.8 @@ -61,7 +61,10 @@ line. Blank lines and lines starting with the comment character .Ql \&# are ignored. .Pp -The shared libraries so found will be automatically available for loading +For security reasons, directories which are world-writable or which +are not owned by root produce warning messages and are skipped. +.Pp +The shared libraries which are found will be automatically available for loading if needed by the program being prepared for execution. This obviates the need for storing search paths within the executable. @@ -137,9 +140,6 @@ In addition to building a set of hints for quick lookup, it also serves to specify the trusted collection of directories from which shared objects can be safely loaded. -It is presumed that the set of directories specified to -.Nm ldconfig -are under control of the system's administrator. .Sh ENVIRONMENT .Bl -tag -width OBJFORMATxxx -compact .It Ev OBJFORMAT diff --git a/sbin/ldconfig/ldconfig.c b/sbin/ldconfig/ldconfig.c index 76f8299cfa43..cde4f9a69648 100644 --- a/sbin/ldconfig/ldconfig.c +++ b/sbin/ldconfig/ldconfig.c @@ -259,6 +259,7 @@ int silent; { DIR *dd; struct dirent *dp; + struct stat stbuf; char name[MAXPATHLEN]; int dewey[MAXDEWEY], ndewey; @@ -269,6 +270,20 @@ int silent; return -1; } + /* Do some security checks */ + if (fstat(dirfd(dd), &stbuf) == -1) { + warn("%s", dir); + return -1; + } + if (stbuf.st_uid != 0) { + warnx("%s: not owned by root", dir); + return -1; + } + if ((stbuf.st_mode & S_IWOTH) != 0) { + warnx("%s: ignoring world-writable directory", dir); + return -1; + } + while ((dp = readdir(dd)) != NULL) { register int n; register char *cp;