Skip to content

Commit 79811ed

Browse files
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.
1 parent 5770006 commit 79811ed

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

Lib/test/_test_multiprocessing.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3971,6 +3971,21 @@ def _new_shm_name(self, prefix):
39713971
# test_multiprocessing_spawn, etc) in parallel.
39723972
return prefix + str(os.getpid())
39733973

3974+
def test_shared_memory_name_with_embedded_null(self):
3975+
name_tsmb = self._new_shm_name('test01_null')
3976+
sms = shared_memory.SharedMemory(name_tsmb, create=True, size=512)
3977+
self.addCleanup(sms.unlink)
3978+
with self.assertRaises(ValueError):
3979+
shared_memory.SharedMemory(name_tsmb + '\0a', create=False, size=512)
3980+
if shared_memory._USE_POSIX:
3981+
orig_name = sms._name
3982+
try:
3983+
sms._name = orig_name + '\0a'
3984+
with self.assertRaises(ValueError):
3985+
sms.unlink()
3986+
finally:
3987+
sms._name = orig_name
3988+
39743989
def test_shared_memory_basics(self):
39753990
name_tsmb = self._new_shm_name('test01_tsmb')
39763991
sms = shared_memory.SharedMemory(name_tsmb, create=True, size=512)
@@ -4105,7 +4120,7 @@ def test_shared_memory_recreate(self):
41054120
self.addCleanup(shm2.unlink)
41064121
self.assertEqual(shm2._name, names[1])
41074122

4108-
def test_invalid_shared_memory_cration(self):
4123+
def test_invalid_shared_memory_creation(self):
41094124
# Test creating a shared memory segment with negative size
41104125
with self.assertRaises(ValueError):
41114126
sms_invalid = shared_memory.SharedMemory(create=True, size=-1)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix silent truncation of the name with an embedded null character in
2+
:class:`multiprocessing.shared_memory.SharedMemory`.

Modules/_multiprocessing/posixshmem.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ posixshmem - A Python extension that provides shm_open() and shm_unlink()
1111

1212
#include <Python.h>
1313

14+
#include <string.h> // strlen()
1415
#include <errno.h> // EINTR
1516
#ifdef HAVE_SYS_MMAN_H
1617
# include <sys/mman.h> // shm_open(), shm_unlink()
@@ -48,10 +49,15 @@ _posixshmem_shm_open_impl(PyObject *module, PyObject *path, int flags,
4849
{
4950
int fd;
5051
int async_err = 0;
51-
const char *name = PyUnicode_AsUTF8AndSize(path, NULL);
52+
Py_ssize_t name_size;
53+
const char *name = PyUnicode_AsUTF8AndSize(path, &name_size);
5254
if (name == NULL) {
5355
return -1;
5456
}
57+
if (strlen(name) != (size_t)name_size) {
58+
PyErr_SetString(PyExc_ValueError, "embedded null character");
59+
return -1;
60+
}
5561
do {
5662
Py_BEGIN_ALLOW_THREADS
5763
fd = shm_open(name, flags, mode);
@@ -87,10 +93,15 @@ _posixshmem_shm_unlink_impl(PyObject *module, PyObject *path)
8793
{
8894
int rv;
8995
int async_err = 0;
90-
const char *name = PyUnicode_AsUTF8AndSize(path, NULL);
96+
Py_ssize_t name_size;
97+
const char *name = PyUnicode_AsUTF8AndSize(path, &name_size);
9198
if (name == NULL) {
9299
return NULL;
93100
}
101+
if (strlen(name) != (size_t)name_size) {
102+
PyErr_SetString(PyExc_ValueError, "embedded null character");
103+
return NULL;
104+
}
94105
do {
95106
Py_BEGIN_ALLOW_THREADS
96107
rv = shm_unlink(name);

0 commit comments

Comments
 (0)