summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/exec
diff options
context:
space:
mode:
authorCody Peter Mello <cody.mello@joyent.com>2019-03-04 18:03:47 +0000
committerCody Peter Mello <melloc@writev.io>2019-03-04 21:29:03 +0000
commit31fd5d7bc7a22f5f61d4a1b782a407e05cf49ad1 (patch)
treefe62b30e1d4a58fefb5d0cddfde0694b41b8a393 /usr/src/uts/common/exec
parentd959f82bb4585e1dbd808a8420514ca76a20b9e1 (diff)
downloadillumos-joyent-31fd5d7bc7a22f5f61d4a1b782a407e05cf49ad1.tar.gz
OS-7630 elfexec() should keep to unsigned types when processing PT_DYNAMIC
Reviewed by: Richard Lowe <richlowe@richlowe.net> Reviewed by: Patrick Mooney <patrick.mooney@joyent.com> Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/uts/common/exec')
-rw-r--r--usr/src/uts/common/exec/elf/elf.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/usr/src/uts/common/exec/elf/elf.c b/usr/src/uts/common/exec/elf/elf.c
index 87bf950a30..0b4e70cad3 100644
--- a/usr/src/uts/common/exec/elf/elf.c
+++ b/usr/src/uts/common/exec/elf/elf.c
@@ -26,7 +26,7 @@
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
- * Copyright (c) 2018, Joyent, Inc.
+ * Copyright (c) 2019, Joyent, Inc.
*/
#include <sys/types.h>
@@ -377,16 +377,16 @@ elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
Phdr *uphdr = NULL;
Phdr *junk = NULL;
size_t len;
+ size_t i;
ssize_t phdrsize;
int postfixsize = 0;
- int i, hsize;
+ int hsize;
Phdr *phdrp;
Phdr *dataphdrp = NULL;
Phdr *dtrphdr;
Phdr *capphdr = NULL;
Cap *cap = NULL;
ssize_t capsize;
- Dyn *dyn = NULL;
int hasu = 0;
int hasauxv = 0;
int hasintp = 0;
@@ -663,24 +663,30 @@ elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
}
/* If the binary has an explicit ASLR flag, it must be honoured */
- if ((dynamicphdr != NULL) &&
- (dynamicphdr->p_filesz > 0)) {
- Dyn *dp;
- off_t i = 0;
+ if ((dynamicphdr != NULL) && (dynamicphdr->p_filesz > 0)) {
+ const size_t dynfilesz = dynamicphdr->p_filesz;
+ const size_t dynoffset = dynamicphdr->p_offset;
+ Dyn *dyn, *dp;
+
+ if (dynoffset > MAXOFFSET_T ||
+ dynfilesz > MAXOFFSET_T ||
+ dynoffset + dynfilesz > MAXOFFSET_T) {
+ uprintf("%s: cannot read full .dynamic section\n",
+ exec_file);
+ error = EINVAL;
+ goto out;
+ }
#define DYN_STRIDE 100
- for (i = 0; i < dynamicphdr->p_filesz;
- i += sizeof (*dyn) * DYN_STRIDE) {
- int ndyns = (dynamicphdr->p_filesz - i) / sizeof (*dyn);
- size_t dynsize;
-
- ndyns = MIN(DYN_STRIDE, ndyns);
- dynsize = ndyns * sizeof (*dyn);
+ for (i = 0; i < dynfilesz; i += sizeof (*dyn) * DYN_STRIDE) {
+ const size_t remdyns = (dynfilesz - i) / sizeof (*dyn);
+ const size_t ndyns = MIN(DYN_STRIDE, remdyns);
+ const size_t dynsize = ndyns * sizeof (*dyn);
dyn = kmem_alloc(dynsize, KM_SLEEP);
if ((error = vn_rdwr(UIO_READ, vp, (caddr_t)dyn,
- dynsize, (offset_t)(dynamicphdr->p_offset + i),
+ (ssize_t)dynsize, (offset_t)(dynoffset + i),
UIO_SYSSPACE, 0, (rlim64_t)0,
CRED(), &resid)) != 0) {
uprintf("%s: cannot read .dynamic section\n",