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.
This commit is contained in:
Serhiy Storchaka 2024-02-25 11:31:03 +02:00 committed by GitHub
parent 5770006ffa
commit 79811ededd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 3 deletions

View File

@ -3971,6 +3971,21 @@ class _TestSharedMemory(BaseTestCase):
# test_multiprocessing_spawn, etc) in parallel. # test_multiprocessing_spawn, etc) in parallel.
return prefix + str(os.getpid()) 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): def test_shared_memory_basics(self):
name_tsmb = self._new_shm_name('test01_tsmb') name_tsmb = self._new_shm_name('test01_tsmb')
sms = shared_memory.SharedMemory(name_tsmb, create=True, size=512) sms = shared_memory.SharedMemory(name_tsmb, create=True, size=512)
@ -4105,7 +4120,7 @@ class _TestSharedMemory(BaseTestCase):
self.addCleanup(shm2.unlink) self.addCleanup(shm2.unlink)
self.assertEqual(shm2._name, names[1]) 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 # Test creating a shared memory segment with negative size
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
sms_invalid = shared_memory.SharedMemory(create=True, size=-1) sms_invalid = shared_memory.SharedMemory(create=True, size=-1)

View File

@ -0,0 +1,2 @@
Fix silent truncation of the name with an embedded null character in
:class:`multiprocessing.shared_memory.SharedMemory`.

View File

@ -11,6 +11,7 @@ posixshmem - A Python extension that provides shm_open() and shm_unlink()
#include <Python.h> #include <Python.h>
#include <string.h> // strlen()
#include <errno.h> // EINTR #include <errno.h> // EINTR
#ifdef HAVE_SYS_MMAN_H #ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h> // shm_open(), shm_unlink() # 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 fd;
int async_err = 0; 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) { if (name == NULL) {
return -1; return -1;
} }
if (strlen(name) != (size_t)name_size) {
PyErr_SetString(PyExc_ValueError, "embedded null character");
return -1;
}
do { do {
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
fd = shm_open(name, flags, mode); fd = shm_open(name, flags, mode);
@ -87,10 +93,15 @@ _posixshmem_shm_unlink_impl(PyObject *module, PyObject *path)
{ {
int rv; int rv;
int async_err = 0; 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) { if (name == NULL) {
return NULL; return NULL;
} }
if (strlen(name) != (size_t)name_size) {
PyErr_SetString(PyExc_ValueError, "embedded null character");
return NULL;
}
do { do {
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
rv = shm_unlink(name); rv = shm_unlink(name);