mm: fix move/migrate_pages() race on task struct
authorChristoph Lameter <cl@linux.com>
Wed, 21 Mar 2012 23:34:06 +0000 (16:34 -0700)
committerBen Hutchings <ben@decadent.org.uk>
Fri, 15 Sep 2017 17:30:57 +0000 (18:30 +0100)
commit5e7b05a3a1aed0d2b8ecd85188554a44161133b5
treee4388d370bb652efa9ab99dc0a70ba41b31e391a
parent1c8d42255f4c55f9550f72bbcda758aeff3fd7c2
mm: fix move/migrate_pages() race on task struct

commit 3268c63eded4612a3d07b56d1e02ce7731e6608e upstream.

Migration functions perform the rcu_read_unlock too early.  As a result
the task pointed to may change from under us.  This can result in an oops,
as reported by Dave Hansen in https://lkml.org/lkml/2012/2/23/302.

The following patch extend the period of the rcu_read_lock until after the
permissions checks are done.  We also take a refcount so that the task
reference is stable when calling security check functions and performing
cpuset node validation (which takes a mutex).

The refcount is dropped before actual page migration occurs so there is no
change to the refcounts held during page migration.

Also move the determination of the mm of the task struct to immediately
before the do_migrate*() calls so that it is clear that we switch from
handling the task during permission checks to the mm for the actual
migration.  Since the determination is only done once and we then no
longer use the task_struct we can be sure that we operate on a specific
address space that will not change from under us.

[akpm@linux-foundation.org: checkpatch fixes]
Signed-off-by: Christoph Lameter <cl@linux.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Reported-by: Dave Hansen <dave@linux.vnet.ibm.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Hugh Dickins <hughd@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
mm/mempolicy.c
mm/migrate.c