https://github.com/python/cpython/commit/79811ededd160b6e8bcfbe4b0f9d5b4589280f19
commit: 79811ededd160b6e8bcfbe4b0f9d5b4589280f19
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2024-02-25T11:31:03+02:00
summary:

gh-115886: Handle embedded null characters in shared memory name (GH-115887)

shm_open() and shm_unlink() now check for embedded null characters in
the name and raise an error instead of silently truncating it.

files:
A Misc/NEWS.d/next/Library/2024-02-24-18-48-14.gh-issue-115886.rgM6AF.rst
M Lib/test/_test_multiprocessing.py
M Modules/_multiprocessing/posixshmem.c

diff --git a/Lib/test/_test_multiprocessing.py 
b/Lib/test/_test_multiprocessing.py
index e4183eea959dd5..f70a693e641b4e 100644
--- a/Lib/test/_test_multiprocessing.py
+++ b/Lib/test/_test_multiprocessing.py
@@ -3971,6 +3971,21 @@ def _new_shm_name(self, prefix):
         # test_multiprocessing_spawn, etc) in parallel.
         return prefix + str(os.getpid())
 
+    def test_shared_memory_name_with_embedded_null(self):
+        name_tsmb = self._new_shm_name('test01_null')
+        sms = shared_memory.SharedMemory(name_tsmb, create=True, size=512)
+        self.addCleanup(sms.unlink)
+        with self.assertRaises(ValueError):
+            shared_memory.SharedMemory(name_tsmb + '\0a', create=False, 
size=512)
+        if shared_memory._USE_POSIX:
+            orig_name = sms._name
+            try:
+                sms._name = orig_name + '\0a'
+                with self.assertRaises(ValueError):
+                    sms.unlink()
+            finally:
+                sms._name = orig_name
+
     def test_shared_memory_basics(self):
         name_tsmb = self._new_shm_name('test01_tsmb')
         sms = shared_memory.SharedMemory(name_tsmb, create=True, size=512)
@@ -4105,7 +4120,7 @@ def test_shared_memory_recreate(self):
             self.addCleanup(shm2.unlink)
             self.assertEqual(shm2._name, names[1])
 
-    def test_invalid_shared_memory_cration(self):
+    def test_invalid_shared_memory_creation(self):
         # Test creating a shared memory segment with negative size
         with self.assertRaises(ValueError):
             sms_invalid = shared_memory.SharedMemory(create=True, size=-1)
diff --git 
a/Misc/NEWS.d/next/Library/2024-02-24-18-48-14.gh-issue-115886.rgM6AF.rst 
b/Misc/NEWS.d/next/Library/2024-02-24-18-48-14.gh-issue-115886.rgM6AF.rst
new file mode 100644
index 00000000000000..9688f713d5ba7b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-02-24-18-48-14.gh-issue-115886.rgM6AF.rst
@@ -0,0 +1,2 @@
+Fix silent truncation of the name with an embedded null character in
+:class:`multiprocessing.shared_memory.SharedMemory`.
diff --git a/Modules/_multiprocessing/posixshmem.c 
b/Modules/_multiprocessing/posixshmem.c
index 425ce10075c156..4ab15fa6573665 100644
--- a/Modules/_multiprocessing/posixshmem.c
+++ b/Modules/_multiprocessing/posixshmem.c
@@ -11,6 +11,7 @@ posixshmem - A Python extension that provides shm_open() and 
shm_unlink()
 
 #include <Python.h>
 
+#include <string.h>               // strlen()
 #include <errno.h>                // EINTR
 #ifdef HAVE_SYS_MMAN_H
 #  include <sys/mman.h>           // shm_open(), shm_unlink()
@@ -48,10 +49,15 @@ _posixshmem_shm_open_impl(PyObject *module, PyObject *path, 
int flags,
 {
     int fd;
     int async_err = 0;
-    const char *name = PyUnicode_AsUTF8AndSize(path, NULL);
+    Py_ssize_t name_size;
+    const char *name = PyUnicode_AsUTF8AndSize(path, &name_size);
     if (name == NULL) {
         return -1;
     }
+    if (strlen(name) != (size_t)name_size) {
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        return -1;
+    }
     do {
         Py_BEGIN_ALLOW_THREADS
         fd = shm_open(name, flags, mode);
@@ -87,10 +93,15 @@ _posixshmem_shm_unlink_impl(PyObject *module, PyObject 
*path)
 {
     int rv;
     int async_err = 0;
-    const char *name = PyUnicode_AsUTF8AndSize(path, NULL);
+    Py_ssize_t name_size;
+    const char *name = PyUnicode_AsUTF8AndSize(path, &name_size);
     if (name == NULL) {
         return NULL;
     }
+    if (strlen(name) != (size_t)name_size) {
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        return NULL;
+    }
     do {
         Py_BEGIN_ALLOW_THREADS
         rv = shm_unlink(name);

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to