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.
Showing the changes to kernel/fork.c (1 of 1 file). Show all
Unified · Split
| @@ -374,6 +374,11 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) · 373 unmodified lines | |||
| 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; |