summaryrefslogtreecommitdiff
path: root/libexec/ld.so/sod.c
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/ld.so/sod.c')
-rw-r--r--libexec/ld.so/sod.c67
1 files changed, 28 insertions, 39 deletions
diff --git a/libexec/ld.so/sod.c b/libexec/ld.so/sod.c
index f8589611ddf..eb42997162b 100644
--- a/libexec/ld.so/sod.c
+++ b/libexec/ld.so/sod.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sod.c,v 1.16 2003/02/02 16:57:58 deraadt Exp $ */
+/* $OpenBSD: sod.c,v 1.17 2003/05/08 16:30:52 millert Exp $ */
/*
* Copyright (c) 1993 Paul Kranenburg
@@ -37,6 +37,7 @@
#include <fcntl.h>
#include <nlist.h>
#include <link.h>
+#include <limits.h>
#include <machine/exec.h>
#include <sys/mman.h>
#include <string.h>
@@ -48,7 +49,6 @@
#include "util.h"
#include "sod.h"
-#define PAGSIZ __LDPGSZ
int _dl_hinthash(char *cp, int vmajor, int vminor);
/*
@@ -129,8 +129,6 @@ backout:
sodp->sod_name = (long)_dl_strdup(name);
}
-static int hfd;
-static long hsize;
static struct hints_header *hheader = NULL;
static struct hints_bucket *hbuckets;
static char *hstrtab;
@@ -141,48 +139,30 @@ char *_dl_hint_search_path = NULL;
void
_dl_maphints(void)
{
- caddr_t addr;
+ struct stat sb;
+ caddr_t addr = MAP_FAILED;
+ long hsize = 0;
+ int hfd;
- if ((hfd = _dl_open(_PATH_LD_HINTS, O_RDONLY)) < 0) {
- hheader = (struct hints_header *)-1;
- return;
- }
+ if ((hfd = _dl_open(_PATH_LD_HINTS, O_RDONLY)) < 0)
+ goto bad_hints;
- hsize = PAGSIZ;
- addr = (void *) _dl_mmap(0, hsize, PROT_READ, MAP_PRIVATE, hfd, 0);
+ if (_dl_fstat(hfd, &sb) != 0 || !S_ISREG(sb.st_mode) ||
+ sb.st_size < sizeof(struct hints_header) || sb.st_size > LONG_MAX)
+ goto bad_hints;
- if (addr == MAP_FAILED) {
- _dl_close(hfd);
- hheader = (struct hints_header *)-1;
- return;
- }
+ hsize = (long)sb.st_size;
+ addr = (void *)_dl_mmap(0, hsize, PROT_READ, MAP_PRIVATE, hfd, 0);
+ if (addr == MAP_FAILED)
+ goto bad_hints;
hheader = (struct hints_header *)addr;
- if (HH_BADMAG(*hheader)) {
- _dl_munmap(addr, hsize);
- _dl_close(hfd);
- hheader = (struct hints_header *)-1;
- return;
- }
+ if (HH_BADMAG(*hheader) || hheader->hh_ehints > hsize)
+ goto bad_hints;
if (hheader->hh_version != LD_HINTS_VERSION_1 &&
- hheader->hh_version != LD_HINTS_VERSION_2) {
- _dl_munmap(addr, hsize);
- _dl_close(hfd);
- hheader = (struct hints_header *)-1;
- return;
- }
-
- if (hheader->hh_ehints > hsize) {
- if ((caddr_t)_dl_mmap(addr+hsize, hheader->hh_ehints - hsize,
- PROT_READ, MAP_PRIVATE|MAP_FIXED,
- hfd, hsize) != (caddr_t)(addr+hsize)) {
- _dl_munmap((caddr_t)hheader, hsize);
- _dl_close(hfd);
- hheader = (struct hints_header *)-1;
- return;
- }
- }
+ hheader->hh_version != LD_HINTS_VERSION_2)
+ goto bad_hints;
hbuckets = (struct hints_bucket *)(addr + hheader->hh_hashtab);
hstrtab = (char *)(addr + hheader->hh_strtab);
@@ -191,6 +171,15 @@ _dl_maphints(void)
/* close the file descriptor, leaving the hints mapped */
_dl_close(hfd);
+
+ return;
+
+bad_hints:
+ if (addr != MAP_FAILED)
+ _dl_munmap(addr, hsize);
+ if (hfd != -1)
+ _dl_close(hfd);
+ hheader = (struct hints_header *)-1;
}
char *