summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVijayanand Jitta <vjitta@codeaurora.org>2019-10-23 10:03:55 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2020-09-14 22:09:55 -0700
commit90cbaf5095aa53f37dca49c4e5b2593518cfa955 (patch)
treee6361995fe4566610d25c7a722b30fd13ccabceb
parent353b81f1fbec379322908cec16dcb7f6b3167fb6 (diff)
ANDROID: Take reference to task_struct with in the rcu section
An issue is reported where the following sequence occurred 1) In lowmem_scan path, task to kill gets selected and SIGKILL is sent. 2) Task receives the signal or it can already be in its exit path and it does put_task_struct which makes cred as NULL. 3) Now in lowmem_scan path get_task_struct is done followed by put_task_struct which will result in accessing cred which is already NULL. Unable to handle kernel NULL pointer dereference at virtual address 00000000 ... PC is at exit_creds+0x1c/0x70 LR is at __put_task_struct+0x44/0x134 [<000000003316722f>] exit_creds+0x1c/0x70 [<000000004966ea42>] __put_task_struct+0x44/0x134 [<000000004fa7fb71>] lowmem_scan+0x6f8/0x1078 [<000000007d2818cd>] shrink_slab.part.65+0x1fc/0x4e8 [<00000000cb140f16>] shrink_node+0x9c/0x20c [<00000000afe7461e>] kswapd+0x28c/0x534 [<000000003df446ee>] kthread+0xe0/0xf4 [<00000000f357571f>] ret_from_fork+0x10/0x20 To avoid this take reference to task struct with in the rcu section so that the task_struct remains intact. Change-Id: I2752cb17768cc6011502688212040bf90b0c56e7 Signed-off-by: Vijayanand Jitta <vjitta@codeaurora.org>
-rw-r--r--drivers/staging/android/lowmemorykiller.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index ee4c11b4e164..62a51d9b7611 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -665,6 +665,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
}
task_lock(selected);
+ get_task_struct(selected);
send_sig(SIGKILL, selected, 0);
/*
* FIXME: lowmemorykiller shouldn't abuse global OOM killer
@@ -713,7 +714,6 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
lowmem_deathpending_timeout = jiffies + HZ;
rem += selected_tasksize;
rcu_read_unlock();
- get_task_struct(selected);
/* give the system time to free up the memory */
msleep_interruptible(20);
trace_almk_shrink(selected_tasksize, ret,