Commit a3a2e76c authored by KAMEZAWA Hiroyuki's avatar KAMEZAWA Hiroyuki Committed by Linus Torvalds

mm: avoid null-pointer deref in sync_mm_rss()

- We weren't zeroing p->rss_stat[] at fork()

- Consequently sync_mm_rss() was dereferencing tsk->mm for kernel
  threads and was oopsing.

- Make __sync_task_rss_stat() static, too.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=15648

[akpm@linux-foundation.org: remove the BUG_ON(!mm->rss)]
Reported-by: default avatarTroels Liebe Bentsen <tlb@rapanden.dk>
Signed-off-by: default avatarKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
"Michael S. Tsirkin" <mst@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Minchan Kim <minchan.kim@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b01d0942
...@@ -953,7 +953,8 @@ NORET_TYPE void do_exit(long code) ...@@ -953,7 +953,8 @@ NORET_TYPE void do_exit(long code)
acct_update_integrals(tsk); acct_update_integrals(tsk);
/* sync mm's RSS info before statistics gathering */ /* sync mm's RSS info before statistics gathering */
sync_mm_rss(tsk, tsk->mm); if (tsk->mm)
sync_mm_rss(tsk, tsk->mm);
group_dead = atomic_dec_and_test(&tsk->signal->live); group_dead = atomic_dec_and_test(&tsk->signal->live);
if (group_dead) { if (group_dead) {
hrtimer_cancel(&tsk->signal->real_timer); hrtimer_cancel(&tsk->signal->real_timer);
......
...@@ -1052,6 +1052,9 @@ static struct task_struct *copy_process(unsigned long clone_flags, ...@@ -1052,6 +1052,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->prev_utime = cputime_zero; p->prev_utime = cputime_zero;
p->prev_stime = cputime_zero; p->prev_stime = cputime_zero;
#endif #endif
#if defined(SPLIT_RSS_COUNTING)
memset(&p->rss_stat, 0, sizeof(p->rss_stat));
#endif
p->default_timer_slack_ns = current->timer_slack_ns; p->default_timer_slack_ns = current->timer_slack_ns;
......
...@@ -125,13 +125,12 @@ core_initcall(init_zero_pfn); ...@@ -125,13 +125,12 @@ core_initcall(init_zero_pfn);
#if defined(SPLIT_RSS_COUNTING) #if defined(SPLIT_RSS_COUNTING)
void __sync_task_rss_stat(struct task_struct *task, struct mm_struct *mm) static void __sync_task_rss_stat(struct task_struct *task, struct mm_struct *mm)
{ {
int i; int i;
for (i = 0; i < NR_MM_COUNTERS; i++) { for (i = 0; i < NR_MM_COUNTERS; i++) {
if (task->rss_stat.count[i]) { if (task->rss_stat.count[i]) {
BUG_ON(!mm);
add_mm_counter(mm, i, task->rss_stat.count[i]); add_mm_counter(mm, i, task->rss_stat.count[i]);
task->rss_stat.count[i] = 0; task->rss_stat.count[i] = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment