Unverified Commit c49017f9 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!13215 fork: do not expose incomplete mm on fork

Merge Pull Request from: @ci-robot 
 
PR sync from: Jinjiang Tu <tujinjiang@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/7EDK2WQ23XPYGASAQUCRTK66HOSWBCVB/ 
Jinjiang Tu (1):
  mm/ksm: remove redundant code in ksm_fork

Lorenzo Stoakes (2):
  fork: do not invoke uffd on fork if error occurs
  fork: only invoke khugepaged, ksm hooks if no error


-- 
2.34.1
 
https://gitee.com/openeuler/kernel/issues/IB23JR 
 
Link:https://gitee.com/openeuler/kernel/pulls/13215

 

Reviewed-by: default avatarKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents 7c547c6b fcc2e046
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -777,6 +777,34 @@ void dup_userfaultfd_complete(struct list_head *fcs)
	}
}

void dup_userfaultfd_fail(struct list_head *fcs)
{
	struct userfaultfd_fork_ctx *fctx, *n;

	/*
	 * An error has occurred on fork, we will tear memory down, but have
	 * allocated memory for fctx's and raised reference counts for both the
	 * original and child contexts (and on the mm for each as a result).
	 *
	 * These would ordinarily be taken care of by a user handling the event,
	 * but we are no longer doing so, so manually clean up here.
	 *
	 * mm tear down will take care of cleaning up VMA contexts.
	 */
	list_for_each_entry_safe(fctx, n, fcs, list) {
		struct userfaultfd_ctx *octx = fctx->orig;
		struct userfaultfd_ctx *ctx = fctx->new;

		atomic_dec(&octx->mmap_changing);
		VM_BUG_ON(atomic_read(&octx->mmap_changing) < 0);
		userfaultfd_ctx_put(octx);
		userfaultfd_ctx_put(ctx);

		list_del(&fctx->list);
		kfree(fctx);
	}
}

void mremap_userfaultfd_prep(struct vm_area_struct *vma,
			     struct vm_userfaultfd_ctx *vm_ctx)
{
+4 −15
Original line number Diff line number Diff line
@@ -54,20 +54,10 @@ static inline long mm_ksm_zero_pages(struct mm_struct *mm)
	return atomic_long_read(&mm->ksm_zero_pages);
}

static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
static inline void ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
{
	int ret;

	if (test_bit(MMF_VM_MERGEABLE, &oldmm->flags)) {
		ret = __ksm_enter(mm);
		if (ret)
			return ret;
	}

	if (test_bit(MMF_VM_MERGE_ANY, &oldmm->flags))
		set_bit(MMF_VM_MERGE_ANY, &mm->flags);

	return 0;
	if (test_bit(MMF_VM_MERGEABLE, &oldmm->flags))
		__ksm_enter(mm);
}

static inline void ksm_exit(struct mm_struct *mm)
@@ -111,9 +101,8 @@ static inline int ksm_disable(struct mm_struct *mm)
	return 0;
}

static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
static inline void ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
{
	return 0;
}

static inline void ksm_exit(struct mm_struct *mm)
+5 −0
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@ static inline bool vma_can_userfault(struct vm_area_struct *vma,

extern int dup_userfaultfd(struct vm_area_struct *, struct list_head *);
extern void dup_userfaultfd_complete(struct list_head *);
void dup_userfaultfd_fail(struct list_head *);

extern void mremap_userfaultfd_prep(struct vm_area_struct *,
				    struct vm_userfaultfd_ctx *);
@@ -261,6 +262,10 @@ static inline void dup_userfaultfd_complete(struct list_head *l)
{
}

static inline void dup_userfaultfd_fail(struct list_head *l)
{
}

static inline void mremap_userfaultfd_prep(struct vm_area_struct *vma,
					   struct vm_userfaultfd_ctx *ctx)
{
+6 −6
Original line number Diff line number Diff line
@@ -685,11 +685,6 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
	mm->exec_vm = oldmm->exec_vm;
	mm->stack_vm = oldmm->stack_vm;

	retval = ksm_fork(mm, oldmm);
	if (retval)
		goto out;
	khugepaged_fork(mm, oldmm);

	/* Use __mt_dup() to efficiently build an identical maple tree. */
	retval = __mt_dup(&oldmm->mm_mt, &mm->mm_mt, GFP_KERNEL);
	if (unlikely(retval))
@@ -792,6 +787,8 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
	vma_iter_free(&vmi);
	if (!retval) {
		mt_set_in_rcu(vmi.mas.tree);
		ksm_fork(mm, oldmm);
		khugepaged_fork(mm, oldmm);
	} else if (mpnt) {
		/*
		 * The entire maple tree has already been duplicated. If the
@@ -807,7 +804,10 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
	mmap_write_unlock(mm);
	flush_tlb_mm(oldmm);
	mmap_write_unlock(oldmm);
	if (!retval)
		dup_userfaultfd_complete(&uf);
	else
		dup_userfaultfd_fail(&uf);
fail_uprobe_end:
	uprobe_end_dup_mmap();
	return retval;