Commit 3b34fc5880a2dcc7e5ed9837ef8d6bae051ab266
Committed by
Linus Torvalds
1 parent
72a1de39f8
Exists in
master
and in
4 other branches
elf_core_dump: use rcu_read_lock() to access ->real_parent
In theory it is not safe to dereference ->parent/real_parent without tasklist or rcu lock, we can race with re-parenting. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Roland McGrath <roland@redhat.com> Cc: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 12 additions and 4 deletions Side-by-side Diff
fs/binfmt_elf.c
... | ... | @@ -1340,8 +1340,10 @@ |
1340 | 1340 | prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; |
1341 | 1341 | prstatus->pr_sigpend = p->pending.signal.sig[0]; |
1342 | 1342 | prstatus->pr_sighold = p->blocked.sig[0]; |
1343 | + rcu_read_lock(); | |
1344 | + prstatus->pr_ppid = task_pid_vnr(rcu_dereference(p->real_parent)); | |
1345 | + rcu_read_unlock(); | |
1343 | 1346 | prstatus->pr_pid = task_pid_vnr(p); |
1344 | - prstatus->pr_ppid = task_pid_vnr(p->real_parent); | |
1345 | 1347 | prstatus->pr_pgrp = task_pgrp_vnr(p); |
1346 | 1348 | prstatus->pr_sid = task_session_vnr(p); |
1347 | 1349 | if (thread_group_leader(p)) { |
1348 | 1350 | |
... | ... | @@ -1382,8 +1384,10 @@ |
1382 | 1384 | psinfo->pr_psargs[i] = ' '; |
1383 | 1385 | psinfo->pr_psargs[len] = 0; |
1384 | 1386 | |
1387 | + rcu_read_lock(); | |
1388 | + psinfo->pr_ppid = task_pid_vnr(rcu_dereference(p->real_parent)); | |
1389 | + rcu_read_unlock(); | |
1385 | 1390 | psinfo->pr_pid = task_pid_vnr(p); |
1386 | - psinfo->pr_ppid = task_pid_vnr(p->real_parent); | |
1387 | 1391 | psinfo->pr_pgrp = task_pgrp_vnr(p); |
1388 | 1392 | psinfo->pr_sid = task_session_vnr(p); |
1389 | 1393 |
fs/binfmt_elf_fdpic.c
... | ... | @@ -1387,8 +1387,10 @@ |
1387 | 1387 | prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; |
1388 | 1388 | prstatus->pr_sigpend = p->pending.signal.sig[0]; |
1389 | 1389 | prstatus->pr_sighold = p->blocked.sig[0]; |
1390 | + rcu_read_lock(); | |
1391 | + prstatus->pr_ppid = task_pid_vnr(rcu_dereference(p->real_parent)); | |
1392 | + rcu_read_unlock(); | |
1390 | 1393 | prstatus->pr_pid = task_pid_vnr(p); |
1391 | - prstatus->pr_ppid = task_pid_vnr(p->real_parent); | |
1392 | 1394 | prstatus->pr_pgrp = task_pgrp_vnr(p); |
1393 | 1395 | prstatus->pr_sid = task_session_vnr(p); |
1394 | 1396 | if (thread_group_leader(p)) { |
1395 | 1397 | |
... | ... | @@ -1432,8 +1434,10 @@ |
1432 | 1434 | psinfo->pr_psargs[i] = ' '; |
1433 | 1435 | psinfo->pr_psargs[len] = 0; |
1434 | 1436 | |
1437 | + rcu_read_lock(); | |
1438 | + psinfo->pr_ppid = task_pid_vnr(rcu_dereference(p->real_parent)); | |
1439 | + rcu_read_unlock(); | |
1435 | 1440 | psinfo->pr_pid = task_pid_vnr(p); |
1436 | - psinfo->pr_ppid = task_pid_vnr(p->real_parent); | |
1437 | 1441 | psinfo->pr_pgrp = task_pgrp_vnr(p); |
1438 | 1442 | psinfo->pr_sid = task_session_vnr(p); |
1439 | 1443 |