diff options
author | Vladimir Davydov <vdavydov@parallels.com> | 2014-08-08 17:22:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-08 18:57:23 -0400 |
commit | 4f7d461433bb4a4deee61baefdac6cd1a1ecb546 (patch) | |
tree | fe3609c5e750d4a06876f61ab217503e56b4e182 /kernel | |
parent | ce65cefa5debefc0e81d0a533bda467f0aa67350 (diff) |
fork: copy mm's vm usage counters under mmap_sem
If a forking process has a thread calling (un)mmap (silly but still),
the child process may have some of its mm's vm usage counters (total_vm
and friends) screwed up, because currently they are copied from oldmm
w/o holding any locks (memcpy in dup_mm).
This patch moves the counters initialization to dup_mmap() to be called
under oldmm->mmap_sem, which eliminates any possibility of race.
Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Christoph Lameter <cl@linux.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/fork.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 5a547a59a38a..aff84f84b0d3 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -374,6 +374,11 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
374 | */ | 374 | */ |
375 | down_write_nested(&mm->mmap_sem, SINGLE_DEPTH_NESTING); | 375 | down_write_nested(&mm->mmap_sem, SINGLE_DEPTH_NESTING); |
376 | 376 | ||
377 | mm->total_vm = oldmm->total_vm; | ||
378 | mm->shared_vm = oldmm->shared_vm; | ||
379 | mm->exec_vm = oldmm->exec_vm; | ||
380 | mm->stack_vm = oldmm->stack_vm; | ||
381 | |||
377 | rb_link = &mm->mm_rb.rb_node; | 382 | rb_link = &mm->mm_rb.rb_node; |
378 | rb_parent = NULL; | 383 | rb_parent = NULL; |
379 | pprev = &mm->mmap; | 384 | pprev = &mm->mmap; |