Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109967844
D19715.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D19715.diff
View Options
Index: head/sys/kern/imgact_elf.c
===================================================================
--- head/sys/kern/imgact_elf.c
+++ head/sys/kern/imgact_elf.c
@@ -88,7 +88,7 @@
static int __elfN(check_header)(const Elf_Ehdr *hdr);
static Elf_Brandinfo *__elfN(get_brandinfo)(struct image_params *imgp,
- const char *interp, int interp_name_len, int32_t *osrel, uint32_t *fctl0);
+ const char *interp, int32_t *osrel, uint32_t *fctl0);
static int __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
u_long *entry);
static int __elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset,
@@ -272,13 +272,15 @@
static Elf_Brandinfo *
__elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
- int interp_name_len, int32_t *osrel, uint32_t *fctl0)
+ int32_t *osrel, uint32_t *fctl0)
{
const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
Elf_Brandinfo *bi, *bi_m;
boolean_t ret;
- int i;
+ int i, interp_name_len;
+ interp_name_len = interp != NULL ? strlen(interp) : 0;
+
/*
* We support four types of branding -- (1) the ELF EI_OSABI field
* that SCO added to the ELF spec, (2) FreeBSD 3.x's traditional string
@@ -889,6 +891,60 @@
return (0);
}
+static int
+__elfN(get_interp)(struct image_params *imgp, const Elf_Phdr *phdr,
+ char **interpp, bool *free_interpp)
+{
+ struct thread *td;
+ char *interp;
+ int error, interp_name_len;
+
+ KASSERT(phdr->p_type == PT_INTERP,
+ ("%s: p_type %u != PT_INTERP", __func__, phdr->p_type));
+ KASSERT(VOP_ISLOCKED(imgp->vp),
+ ("%s: vp %p is not locked", __func__, imgp->vp));
+
+ td = curthread;
+
+ /* Path to interpreter */
+ if (phdr->p_filesz < 2 || phdr->p_filesz > MAXPATHLEN) {
+ uprintf("Invalid PT_INTERP\n");
+ return (ENOEXEC);
+ }
+
+ interp_name_len = phdr->p_filesz;
+ if (phdr->p_offset > PAGE_SIZE ||
+ interp_name_len > PAGE_SIZE - phdr->p_offset) {
+ VOP_UNLOCK(imgp->vp, 0);
+ interp = malloc(interp_name_len + 1, M_TEMP, M_WAITOK);
+ vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
+ error = vn_rdwr(UIO_READ, imgp->vp, interp,
+ interp_name_len, phdr->p_offset,
+ UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
+ NOCRED, NULL, td);
+ if (error != 0) {
+ free(interp, M_TEMP);
+ uprintf("i/o error PT_INTERP %d\n", error);
+ return (error);
+ }
+ interp[interp_name_len] = '\0';
+
+ *interpp = interp;
+ *free_interpp = true;
+ return (0);
+ }
+
+ interp = __DECONST(char *, imgp->image_header) + phdr->p_offset;
+ if (interp[interp_name_len - 1] != '\0') {
+ uprintf("Invalid PT_INTERP\n");
+ return (ENOEXEC);
+ }
+
+ *interpp = interp;
+ *free_interpp = false;
+ return (0);
+}
+
/*
* Impossible et_dyn_addr initial value indicating that the real base
* must be calculated later with some randomization applied.
@@ -905,7 +961,7 @@
struct vmspace *vmspace;
vm_map_t map;
const char *newinterp;
- char *interp, *interp_buf, *path;
+ char *interp, *path;
Elf_Brandinfo *brand_info;
struct sysentvec *sv;
vm_prot_t prot;
@@ -913,7 +969,8 @@
u_long maxalign, mapsz, maxv, maxv1;
uint32_t fctl0;
int32_t osrel;
- int error, i, n, interp_name_len, have_interp;
+ bool free_interp;
+ int error, i, n, have_interp;
hdr = (const Elf_Ehdr *)imgp->image_header;
@@ -949,9 +1006,8 @@
osrel = 0;
fctl0 = 0;
entry = proghdr = 0;
- interp_name_len = 0;
- newinterp = NULL;
- interp = interp_buf = NULL;
+ newinterp = interp = NULL;
+ free_interp = false;
td = curthread;
maxalign = PAGE_SIZE;
mapsz = 0;
@@ -968,44 +1024,15 @@
break;
case PT_INTERP:
/* Path to interpreter */
- if (phdr[i].p_filesz < 2 ||
- phdr[i].p_filesz > MAXPATHLEN) {
- uprintf("Invalid PT_INTERP\n");
- error = ENOEXEC;
- goto ret;
- }
if (interp != NULL) {
uprintf("Multiple PT_INTERP headers\n");
error = ENOEXEC;
goto ret;
}
- interp_name_len = phdr[i].p_filesz;
- if (phdr[i].p_offset > PAGE_SIZE ||
- interp_name_len > PAGE_SIZE - phdr[i].p_offset) {
- VOP_UNLOCK(imgp->vp, 0);
- interp_buf = malloc(interp_name_len + 1, M_TEMP,
- M_WAITOK);
- vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
- error = vn_rdwr(UIO_READ, imgp->vp, interp_buf,
- interp_name_len, phdr[i].p_offset,
- UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
- NOCRED, NULL, td);
- if (error != 0) {
- uprintf("i/o error PT_INTERP %d\n",
- error);
- goto ret;
- }
- interp_buf[interp_name_len] = '\0';
- interp = interp_buf;
- } else {
- interp = __DECONST(char *, imgp->image_header) +
- phdr[i].p_offset;
- if (interp[interp_name_len - 1] != '\0') {
- uprintf("Invalid PT_INTERP\n");
- error = ENOEXEC;
- goto ret;
- }
- }
+ error = __elfN(get_interp)(imgp, &phdr[i], &interp,
+ &free_interp);
+ if (error != 0)
+ goto ret;
break;
case PT_GNU_STACK:
if (__elfN(nxstack))
@@ -1016,8 +1043,7 @@
}
}
- brand_info = __elfN(get_brandinfo)(imgp, interp, interp_name_len,
- &osrel, &fctl0);
+ brand_info = __elfN(get_brandinfo)(imgp, interp, &osrel, &fctl0);
if (brand_info == NULL) {
uprintf("ELF binary type \"%u\" not known.\n",
hdr->e_ident[EI_OSABI]);
@@ -1238,7 +1264,8 @@
imgp->proc->p_elf_flags = hdr->e_flags;
ret:
- free(interp_buf, M_TEMP);
+ if (free_interp)
+ free(interp, M_TEMP);
return (error);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Feb 12, 9:04 PM (19 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16616423
Default Alt Text
D19715.diff (5 KB)
Attached To
Mode
D19715: Factor out retrieving the interpreter path from the main ELF loader routine.
Attached
Detach File
Event Timeline
Log In to Comment