Page MenuHomeFreeBSD

D54438.id169062.diff
No OneTemporary

D54438.id169062.diff

diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -155,7 +155,7 @@
c_linker_sym_t *, long *);
static void link_elf_unload_file(linker_file_t);
-static void link_elf_unload_preload(linker_file_t);
+static void link_elf_unload_preload(elf_file_t);
static int link_elf_lookup_set(linker_file_t, const char *,
void ***, void ***, int *);
static int link_elf_each_function_name(linker_file_t,
@@ -799,10 +799,10 @@
/*
* Apply the specified protection to the loadable segments of a preloaded linker
- * file.
+ * file. If "reset" is not set, the original segment protections are ORed in.
*/
static int
-preload_protect(elf_file_t ef, vm_prot_t prot)
+preload_protect1(elf_file_t ef, vm_prot_t prot, bool reset)
{
#if defined(__aarch64__) || defined(__amd64__)
Elf_Ehdr *hdr;
@@ -818,13 +818,16 @@
if (phdr->p_type != PT_LOAD)
continue;
- nprot = prot | VM_PROT_READ;
- if ((phdr->p_flags & PF_W) != 0)
- nprot |= VM_PROT_WRITE;
- if ((phdr->p_flags & PF_X) != 0)
- nprot |= VM_PROT_EXECUTE;
+ nprot = VM_PROT_NONE;
+ if (!reset) {
+ nprot = VM_PROT_READ;
+ if ((phdr->p_flags & PF_W) != 0)
+ nprot |= VM_PROT_WRITE;
+ if ((phdr->p_flags & PF_X) != 0)
+ nprot |= VM_PROT_EXECUTE;
+ }
error = pmap_change_prot((vm_offset_t)ef->address +
- phdr->p_vaddr, round_page(phdr->p_memsz), nprot);
+ phdr->p_vaddr, round_page(phdr->p_memsz), prot | nprot);
if (error != 0)
break;
}
@@ -834,6 +837,18 @@
#endif
}
+static int
+preload_protect(elf_file_t ef, vm_prot_t prot)
+{
+ return (preload_protect1(ef, prot, false));
+}
+
+static int
+preload_protect_reset(elf_file_t ef, vm_prot_t prot)
+{
+ return (preload_protect1(ef, prot, true));
+}
+
#ifdef __arm__
/*
* Locate the ARM exception/unwind table info for DDB and stack(9) use by
@@ -1396,7 +1411,7 @@
elf_cpu_unload_file(file);
if (ef->preloaded) {
- link_elf_unload_preload(file);
+ link_elf_unload_preload(ef);
return;
}
@@ -1417,11 +1432,15 @@
}
static void
-link_elf_unload_preload(linker_file_t file)
+link_elf_unload_preload(elf_file_t ef)
{
-
- if (file->pathname != NULL)
- preload_delete_name(file->pathname);
+ /*
+ * Reset mapping protections to their original state. This affects the
+ * direct map alias of the module mapping as well.
+ */
+ preload_protect_reset(ef, VM_PROT_RW);
+ if (ef->lf.pathname != NULL)
+ preload_delete_name(ef->lf.pathname);
}
static const char *
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -1305,6 +1305,14 @@
vnet_data_free(ef->progtab[i].addr,
ef->progtab[i].size);
#endif
+ else if (ef->preloaded) {
+ vm_offset_t start, end;
+
+ start = (vm_offset_t)ef->progtab[i].addr;
+ end = start + ef->progtab[i].size;
+ link_elf_protect_range(ef, trunc_page(start),
+ round_page(end), VM_PROT_RW);
+ }
}
}
if (ef->preloaded) {
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -953,14 +953,6 @@
end = trunc_page(start + size);
start = round_page(start);
-#ifdef __amd64__
- /*
- * Preloaded files do not have execute permissions by default on amd64.
- * Restore the default permissions to ensure that the direct map alias
- * is updated.
- */
- pmap_change_prot(start, end - start, VM_PROT_RW);
-#endif
for (va = start; va < end; va += PAGE_SIZE) {
pa = pmap_kextract(va);
m = PHYS_TO_VM_PAGE(pa);

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 11, 3:27 PM (39 m, 25 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27612593
Default Alt Text
D54438.id169062.diff (3 KB)

Event Timeline