Skip to content

gh-105436: the environment block should end with two zero-valued wchar_t values #105495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jun 12, 2023

Conversation

A Unicode environment block is terminated by four zero bytes
@bedevere-bot
Copy link

Most changes to Python require a NEWS entry.

Please add it using the blurb_it web app or the blurb command-line tool.

@ghost
Copy link

ghost commented Jun 8, 2023

All commit authors signed the Contributor License Agreement.
CLA signed

@bedevere-bot
Copy link

Most changes to Python require a NEWS entry.

Please add it using the blurb_it web app or the blurb command-line tool.

Comment on lines 800 to 808
/* A Unicode environment block is terminated by four zero bytes:
two for the last string, two more to terminate the block. */
if (envsize == 0) {
buffer = PyMem_NEW(wchar_t, 2);
p = buffer;
*p++ = L'\0';
*p++ = L'\0';
goto error;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using goto error is misleading. I suggest changing the function's exit label name to "cleanup".

Using PyMem_Calloc() avoids the need to manually zero the buffer for the null characters. Also, make sure to raise a MemoryError exception if allocation fails.

Suggested change
/* A Unicode environment block is terminated by four zero bytes:
two for the last string, two more to terminate the block. */
if (envsize == 0) {
buffer = PyMem_NEW(wchar_t, 2);
p = buffer;
*p++ = L'\0';
*p++ = L'\0';
goto error;
}
if (envsize == 0) {
// A environment block must be terminated by two null characters --
// one for the last string and one for the block.
buffer = PyMem_Calloc(2, sizeof(wchar_t));
if (!buffer) {
PyErr_NoMemory();
}
goto cleanup;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

@sku2000
Copy link
Contributor Author

sku2000 commented Jun 11, 2023

I can't reproduce the problem in the test.
This question may be related to this [issue].(#104791)

@eryksun eryksun requested a review from a team June 11, 2023 13:48
@zooba zooba added needs backport to 3.11 only security fixes needs backport to 3.12 only security fixes labels Jun 12, 2023
@zooba
Copy link
Member

zooba commented Jun 12, 2023

I guess the new test has exposed a leak on Ubuntu that no other tests trigger.

Maybe make the new test Windows only and tag it with this issue? No reason to block your change here - it's definitely not the cause of that leak.

@zooba zooba merged commit 4f7d3b6 into python:main Jun 12, 2023
@miss-islington
Copy link
Contributor

Thanks @sku2000 for the PR, and @zooba for merging it 🌮🎉.. I'm working now to backport this PR to: 3.11, 3.12.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Jun 12, 2023
@bedevere-bot
Copy link

GH-105700 is a backport of this pull request to the 3.12 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.12 only security fixes label Jun 12, 2023
@bedevere-bot
Copy link

GH-105701 is a backport of this pull request to the 3.11 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Jun 12, 2023
@bedevere-bot bedevere-bot removed the needs backport to 3.11 only security fixes label Jun 12, 2023
zooba pushed a commit that referenced this pull request Jun 12, 2023
…r_t values (GH-105495) (#105701)

gh-105436: The environment block should end with two null wchar_t values (GH-105495)
(cherry picked from commit 4f7d3b6)

Co-authored-by: Dora203 <[email protected]>
zooba pushed a commit that referenced this pull request Jun 12, 2023
…r_t values (GH-105495) (#105700)

gh-105436: The environment block should end with two null wchar_t values (GH-105495)
(cherry picked from commit 4f7d3b6)

Co-authored-by: Dora203 <[email protected]>
@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot ARM64 Windows 3.x has failed when building commit 4f7d3b6.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/all/#builders/729/builds/4732) and take a look at the build logs.
  4. Check if the failure is related to this commit (4f7d3b6) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/all/#builders/729/builds/4732

Failed tests:

  • test_subprocess

Failed subtests:

  • test_run_with_an_empty_env - test.test_subprocess.RunFuncTestCase.test_run_with_an_empty_env

Summary of the results of the build (if available):

== Tests result: FAILURE then FAILURE ==

413 tests OK.

10 slowest tests:

  • test_math: 6 min 59 sec
  • test_multiprocessing_spawn: 4 min 32 sec
  • test_peg_generator: 4 min 10 sec
  • test_unparse: 2 min 25 sec
  • test_tokenize: 2 min 23 sec
  • test_tarfile: 2 min 6 sec
  • test_capi: 2 min 2 sec
  • test_unicodedata: 1 min 59 sec
  • test_concurrent_futures: 1 min 47 sec
  • test_fstring: 1 min 39 sec

1 test failed:
test_subprocess

33 tests skipped:
test.test_asyncio.test_unix_events test_curses test_dbm_gnu
test_dbm_ndbm test_devpoll test_epoll test_fcntl test_fork1
test_gdb test_grp test_ioctl test_kqueue test_multiprocessing_fork
test_multiprocessing_forkserver test_openpty test_perf_profiler
test_perfmaps test_poll test_posix test_pty test_pwd test_readline
test_resource test_syslog test_threadsignals test_tkinter test_ttk
test_wait3 test_wait4 test_xxlimited test_xxtestfuzz
test_zipfile64 test_zoneinfo

1 re-run test:
test_subprocess

Total duration: 19 min 51 sec

Click to see traceback logs
Traceback (most recent call last):
  File "C:\Workspace\buildarea\3.x.linaro-win-arm64\build\Lib\test\test_subprocess.py", line 1700, in test_run_with_an_empty_env
    self.assertEqual(res.returncode, 57)
AssertionError: 3221225781 != 57

@eryksun
Copy link
Contributor

eryksun commented Jun 12, 2023

The child process failing at startup with STATUS_DLL_NOT_FOUND (0xC0000135, 3221225781) is probably due to a DLL init routine trying to load another DLL from a path that's based on a standard environment variable, such as SystemRoot. There's really no need to test the exit status. Just assert that OSError isn't raised.

@zooba
Copy link
Member

zooba commented Jun 12, 2023

Are we copying python.exe for this test but not moving python312.dll? That would be causing everything to fail if so.

@eryksun
Copy link
Contributor

eryksun commented Jun 12, 2023

There's already a test_empty_env() test, which is skipped on Windows because the SystemRoot environment variable is required to start Python prior to 3.11. For example, here's 3.10 failing to start:

>>> sys.version_info[:2]
(3, 10)
>>> subprocess.call(sys.executable, env={'a':'b'})
Fatal Python error: _Py_HashRandomization_Init: failed to get random numbers to initialize Python
Python runtime state: preinitialized

The SystemRoot environment variable is no longer required to start Python 3.11+, at least not on x86/x64, because the internal win32_urandom() function was updated to call BCryptGenRandom() instead of CryptAcquireContextW() / CryptGenRandom().

The bot that's failing is an ARM64 system. I don't know whether process initialization under ARM64 depends on SystemRoot or some other environment variable in order to load a library that's particular to the API implementation on ARM64. What I do know is that for this Windows-only test, it doesn't matter whether the child process can start and exit with some know exit status. All we need to check is that the CreateProcessW() call doesn't fail, meaning that in principle it's possible to spawn a child process with an empty environment.

@zooba
Copy link
Member

zooba commented Jun 12, 2023

The ARM64 bot has a slightly different setup compared to the rest of our machines, because it's doing a cross-compile and then running elsewhere. So there might be something critical in PATH. It's unfortunate the Windows logging for DLL errors is so terrible, otherwise we might have a hint.

But you're right, the only important part is the OSError. I've reopened the bug, let's move discussion there.

@sku2000 sku2000 deleted the issues_105436 branch June 14, 2023 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants