summaryrefslogtreecommitdiff
path: root/sys/kern/imgact_elf.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2019-05-16 13:03:54 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2019-05-16 13:03:54 +0000
commit0ddfdc60f80c93c8a2df986e246c92cfdd011bf0 (patch)
tree15124209ae0fbce5571234c74c404342a874e04f /sys/kern/imgact_elf.c
parent98fc918f4183928f9e7e9bf3d7447dea23665032 (diff)
downloadsrc-test2-0ddfdc60f80c93c8a2df986e246c92cfdd011bf0.tar.gz
src-test2-0ddfdc60f80c93c8a2df986e246c92cfdd011bf0.zip
Notes
Diffstat (limited to 'sys/kern/imgact_elf.c')
-rw-r--r--sys/kern/imgact_elf.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 5e198abaad48..687c581d012b 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -935,12 +935,22 @@ __elfN(get_interp)(struct image_params *imgp, const Elf_Phdr *phdr,
interp_name_len = phdr->p_filesz;
if (phdr->p_offset > PAGE_SIZE ||
interp_name_len > PAGE_SIZE - phdr->p_offset) {
+ /*
+ * The vnode lock might be needed by pagedaemon to
+ * clean pages owned by the vnode. Do not allow sleep
+ * waiting for memory with the vnode locked, instead
+ * try non-sleepable allocation first, and if it
+ * fails, go to the slow path were we drop the lock
+ * and do M_WAITOK. Text reference prevents
+ * modifications of the vnode content.
+ */
interp = malloc(interp_name_len + 1, M_TEMP, M_NOWAIT);
if (interp == NULL) {
VOP_UNLOCK(imgp->vp, 0);
interp = malloc(interp_name_len + 1, M_TEMP, M_WAITOK);
vn_lock(imgp->vp, LK_SHARED | LK_RETRY);
}
+
error = vn_rdwr(UIO_READ, imgp->vp, interp,
interp_name_len, phdr->p_offset,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,