diff --git a/sbin/ldconfig/elfhints.c b/sbin/ldconfig/elfhints.c index f7139dfcb0a0..7e5c8e5081bb 100644 --- a/sbin/ldconfig/elfhints.c +++ b/sbin/ldconfig/elfhints.c @@ -46,7 +46,7 @@ #define MAXDIRS 1024 /* Maximum directories in path */ #define MAXFILESIZE (16*1024) /* Maximum hints file size */ -static void add_dir(const char *, const char *); +static void add_dir(const char *, const char *, int); static void read_dirs_from_file(const char *, const char *); static void read_elf_hints(const char *, int); static void write_elf_hints(const char *); @@ -55,23 +55,25 @@ static const char *dirs[MAXDIRS]; static int ndirs; static void -add_dir(const char *hintsfile, const char *name) +add_dir(const char *hintsfile, const char *name, int trusted) { 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; + if (!trusted && !insecure) { + if (stat(name, &stbuf) == -1) { + warn("%s", name); + return; + } + if (stbuf.st_uid != 0) { + warnx("%s: ignoring directory 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++) @@ -170,7 +172,7 @@ read_dirs_from_file(const char *hintsfile, const char *listfile) if ((sp = strdup(sp)) == NULL) errx(1, "Out of memory"); - add_dir(hintsfile, sp); + add_dir(hintsfile, sp, 0); } fclose(fp); @@ -218,7 +220,7 @@ read_elf_hints(const char *hintsfile, int must_exist) if (*dirlist != '\0') while ((p = strsep(&dirlist, ":")) != NULL) - add_dir(hintsfile, p); + add_dir(hintsfile, p, 1); } void @@ -236,7 +238,7 @@ update_elf_hints(const char *hintsfile, int argc, char **argv, int merge) else if (S_ISREG(s.st_mode)) read_dirs_from_file(hintsfile, argv[i]); else - add_dir(hintsfile, argv[i]); + add_dir(hintsfile, argv[i], 0); } write_elf_hints(hintsfile); } diff --git a/sbin/ldconfig/ldconfig.8 b/sbin/ldconfig/ldconfig.8 index f008d90342a6..775f5d48c3ad 100644 --- a/sbin/ldconfig/ldconfig.8 +++ b/sbin/ldconfig/ldconfig.8 @@ -38,7 +38,7 @@ .Sh SYNOPSIS .Nm ldconfig .Op Fl aout | Fl elf -.Op Fl Rmrsv +.Op Fl Rimrsv .Op Fl f Ar hints_file .Op Ar directory | file Ar ... .Sh DESCRIPTION @@ -62,7 +62,8 @@ line. Blank lines and lines starting with the comment character are ignored. .Pp For security reasons, directories which are world-writable or which -are not owned by root produce warning messages and are skipped. +are not owned by root produce warning messages and are skipped, unless +the -i option is present. .Pp The shared libraries which are found will be automatically available for loading if needed by the program being prepared for execution. @@ -104,6 +105,8 @@ This is the default action when no parameters are given. .It Fl f Ar hints_file Read and/or update the specified hints file, instead of the standard file. This option is provided primarily for testing. +.It Fl i +Run in insecure mode. The security checks will not be performed. .It Fl m Instead of replacing the contents of the hints file with those found in the directories specified, @@ -186,3 +189,8 @@ A .Nm utility first appeared in SunOS 4.0, it appeared in its current form in FreeBSD 1.1. +.Sh BUGS +Some security checks (for example, verifying root ownership of +added directories) are not performed when +.Fl aout +is specified. diff --git a/sbin/ldconfig/ldconfig.c b/sbin/ldconfig/ldconfig.c index cde4f9a69648..5c655b45d6ce 100644 --- a/sbin/ldconfig/ldconfig.c +++ b/sbin/ldconfig/ldconfig.c @@ -117,7 +117,7 @@ char *argv[]; hints_file = is_aout ? _PATH_LD_HINTS : _PATH_ELF_HINTS; if (argc == 1) rescan = 1; - else while((c = getopt(argc, argv, "Rf:mrsv")) != -1) { + else while((c = getopt(argc, argv, "Rf:imrsv")) != -1) { switch (c) { case 'R': rescan = 1; @@ -125,6 +125,9 @@ char *argv[]; case 'f': hints_file = optarg; break; + case 'i': + insecure = 1; + break; case 'm': merge = 1; break; @@ -152,6 +155,7 @@ char *argv[]; return 0; } + /* Here begins the aout libs processing */ dir_list = strdup(""); if (justread || merge || rescan) { @@ -209,7 +213,7 @@ static void usage() { fprintf(stderr, - "usage: ldconfig [-aout | -elf] [-Rmrsv] [-f hints_file] [dir | file ...]\n"); + "usage: ldconfig [-aout | -elf] [-Rimrsv] [-f hints_file] [dir | file ...]\n"); exit(1); } @@ -259,7 +263,6 @@ int silent; { DIR *dd; struct dirent *dp; - struct stat stbuf; char name[MAXPATHLEN]; int dewey[MAXDEWEY], ndewey; @@ -270,20 +273,6 @@ 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; diff --git a/sbin/ldconfig/ldconfig.h b/sbin/ldconfig/ldconfig.h index 1ea712c8eb44..71172aa145a5 100644 --- a/sbin/ldconfig/ldconfig.h +++ b/sbin/ldconfig/ldconfig.h @@ -31,6 +31,8 @@ #include +int insecure; /* -i flag, needed here for elfhints.c */ + __BEGIN_DECLS void list_elf_hints __P((const char *)); void update_elf_hints __P((const char *, int, char **, int));