lkml.org 
[lkml]   [2012]   [Aug]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5/5] mempolicy: fix a memory corruption by refcount imbalance in alloc_pages_vma()
    Date
    [cc9a6c87: cpuset: mm: reduce large amounts of memory barrier related damage
    v3] introduced a potential memory corruption. shmem_alloc_page() uses a
    pseudo vma and it has one significant unique combination, vma->vm_ops=NULL
    and vma->policy->flags & MPOL_F_SHARED.

    get_vma_policy() does NOT increase a policy ref when vma->vm_ops=NULL and
    mpol_cond_put() DOES decrease a policy ref when a policy has MPOL_F_SHARED.
    Therefore, when a cpuset update race occurs, alloc_pages_vma() falls in 'goto
    retry_cpuset' path, decrements the reference count and frees the policy
    prematurely.

    Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Signed-off-by: Mel Gorman <mgorman@suse.de>
    ---
    mm/mempolicy.c | 17 +++++++++++++++--
    1 files changed, 15 insertions(+), 2 deletions(-)

    diff --git a/mm/mempolicy.c b/mm/mempolicy.c
    index 45f9825..82e872f 100644
    --- a/mm/mempolicy.c
    +++ b/mm/mempolicy.c
    @@ -1545,15 +1545,28 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
    struct vm_area_struct *vma, unsigned long addr)
    {
    struct mempolicy *pol = task->mempolicy;
    + int got_ref;

    if (vma) {
    if (vma->vm_ops && vma->vm_ops->get_policy) {
    struct mempolicy *vpol = vma->vm_ops->get_policy(vma,
    addr);
    - if (vpol)
    + if (vpol) {
    pol = vpol;
    - } else if (vma->vm_policy)
    + got_ref = 1;
    + }
    + } else if (vma->vm_policy) {
    pol = vma->vm_policy;
    +
    + /*
    + * shmem_alloc_page() passes MPOL_F_SHARED policy with
    + * a pseudo vma whose vma->vm_ops=NULL. Take a reference
    + * count on these policies which will be dropped by
    + * mpol_cond_put() later
    + */
    + if (mpol_needs_cond_ref(pol))
    + mpol_get(pol);
    + }
    }
    if (!pol)
    pol = &default_policy;
    --
    1.7.7


    \
     
     \ /
      Last update: 2012-08-21 06:01    [W:0.026 / U:0.104 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site