bpo-36279: Ensure os.wait3() rusage is initialized (GH-15111)

Co-Authored-By: David Wilson <dw@botanicus.net>
This commit is contained in:
Zackery Spytz 2019-09-09 09:48:32 -06:00 committed by T. Wouters
parent d91d4de317
commit 682107cf45
3 changed files with 25 additions and 0 deletions

View File

@ -2,6 +2,8 @@
"""
import os
import subprocess
import sys
import time
import unittest
from test.fork_wait import ForkWait
@ -31,6 +33,22 @@ class Wait3Test(ForkWait):
self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8))
self.assertTrue(rusage)
def test_wait3_rusage_initialized(self):
# Ensure a successful wait3() call where no child was ready to report
# its exit status does not return uninitialized memory in the rusage
# structure. See bpo-36279.
args = [sys.executable, '-c', 'import sys; sys.stdin.read()']
proc = subprocess.Popen(args, stdin=subprocess.PIPE)
try:
pid, status, rusage = os.wait3(os.WNOHANG)
self.assertEqual(0, pid)
self.assertEqual(0, status)
self.assertEqual(0, sum(rusage))
finally:
proc.stdin.close()
proc.wait()
def tearDownModule():
reap_children()

View File

@ -0,0 +1 @@
Fix potential use of uninitialized memory in :func:`os.wait3`.

View File

@ -7489,6 +7489,12 @@ wait_helper(pid_t pid, int status, struct rusage *ru)
if (pid == -1)
return posix_error();
// If wait succeeded but no child was ready to report status, ru will not
// have been populated.
if (pid == 0) {
memset(ru, 0, sizeof(*ru));
}
if (struct_rusage == NULL) {
PyObject *m = PyImport_ImportModuleNoBlock("resource");
if (m == NULL)