提交 98fe1222 编写于 作者: Z ZhangPeng 提交者: Ma Wupeng

userswap: fix variable uninitialized in uswap_unmap_anon_page()

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6CAIM

--------------------------------

When the pte is none and old_pte is not NULL, _old_pte is uninitialized
and will be passed out of uswap_unmap_anon_page().
To fix this, add a return value to uswap_unmap_anon_page to indicate
whether the pte is none before unmapping.
Signed-off-by: NZhangPeng <zhangpeng362@huawei.com>
上级 f087df84
......@@ -157,24 +157,28 @@ static unsigned long pages_can_be_swapped(struct mm_struct *mm,
return ret;
}
static void uswap_unmap_anon_page(struct mm_struct *mm,
struct vm_area_struct *vma,
unsigned long addr, struct page *page,
pmd_t *pmd, pte_t *old_pte,
bool set_to_swp)
static int uswap_unmap_anon_page(struct mm_struct *mm,
struct vm_area_struct *vma,
unsigned long addr, struct page *page,
pmd_t *pmd, pte_t *old_pte, bool set_to_swp)
{
struct mmu_notifier_range range;
spinlock_t *ptl;
pte_t *pte, _old_pte;
int ret = 0;
mmu_notifier_range_init(&range, MMU_NOTIFY_UNMAP, 0, vma,
vma->vm_mm, addr, addr + PAGE_SIZE);
mmu_notifier_invalidate_range_start(&range);
pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
if (pte_none(*pte))
if (!pte_present(*pte)) {
ret = -EINVAL;
goto out_release_unlock;
}
flush_cache_page(vma, addr, pte_pfn(*pte));
_old_pte = ptep_clear_flush(vma, addr, pte);
if (old_pte)
*old_pte = _old_pte;
if (set_to_swp)
set_pte_at(mm, addr, pte, swp_entry_to_pte(swp_entry(
SWP_USERSWAP_ENTRY, page_to_pfn(page))));
......@@ -182,13 +186,12 @@ static void uswap_unmap_anon_page(struct mm_struct *mm,
dec_mm_counter(mm, MM_ANONPAGES);
reliable_page_counter(page, mm, -1);
page_remove_rmap(page, false);
page->mapping = NULL;
out_release_unlock:
pte_unmap_unlock(pte, ptl);
mmu_notifier_invalidate_range_end(&range);
page->mapping = NULL;
if (old_pte)
*old_pte = _old_pte;
return ret;
}
static void uswap_map_anon_page(struct mm_struct *mm,
......@@ -326,8 +329,10 @@ static unsigned long do_user_swap(struct mm_struct *mm,
pmd = mm_find_pmd(mm, old_addr);
if (!pmd)
goto out_recover;
uswap_unmap_anon_page(mm, old_vma, old_addr, page, pmd,
&old_pte, true);
ret = uswap_unmap_anon_page(mm, old_vma, old_addr, page, pmd,
&old_pte, true);
if (ret)
goto out_recover;
ptes[i] = old_pte;
if (pte_dirty(old_pte) || PageDirty(page))
pages_dirty = true;
......@@ -429,9 +434,10 @@ int mfill_atomic_pte_nocopy(struct mm_struct *mm,
ret = -ENXIO;
goto out_put_page;
}
uswap_unmap_anon_page(mm, src_vma, src_addr, page, src_pmd, &src_pte,
false);
ret = uswap_unmap_anon_page(mm, src_vma, src_addr, page, src_pmd,
&src_pte, false);
if (ret)
goto out_put_page;
if (dst_vma->vm_flags & VM_USWAP)
ClearPageDirty(page);
/*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册