mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-05 06:58:49 +00:00
GstShmAllocator: Seal memfd for future write
The GstMemory we created is kept mapped RW, but any future mapping that uses the fd should be RO. Sponsored-by: Netflix Inc. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5328>
This commit is contained in:
parent
c0ce677dfc
commit
f57dabe65c
1 changed files with 14 additions and 15 deletions
|
@ -62,16 +62,11 @@ gst_shm_allocator_alloc (GstAllocator * allocator, gsize size,
|
||||||
|
|
||||||
#ifdef HAVE_MEMFD_CREATE
|
#ifdef HAVE_MEMFD_CREATE
|
||||||
fd = memfd_create ("gst-shm", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
fd = memfd_create ("gst-shm", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||||
if (fd >= 0) {
|
if (fd < 0) {
|
||||||
/* We can add this seal before calling posix_fallocate(), as
|
GST_ERROR_OBJECT (self, "memfd_create() failed: %s", strerror (errno));
|
||||||
* the file is currently zero-sized anyway.
|
return NULL;
|
||||||
*
|
}
|
||||||
* There is also no need to check for the return value, we
|
#else
|
||||||
* couldn't do anything with it anyway.
|
|
||||||
*/
|
|
||||||
fcntl (fd, F_ADD_SEALS, F_SEAL_SHRINK);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
char filename[1024];
|
char filename[1024];
|
||||||
static int init = 0;
|
static int init = 0;
|
||||||
|
@ -87,6 +82,7 @@ gst_shm_allocator_alloc (GstAllocator * allocator, gsize size,
|
||||||
|
|
||||||
shm_unlink (filename);
|
shm_unlink (filename);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ftruncate (fd, size) < 0) {
|
if (ftruncate (fd, size) < 0) {
|
||||||
GST_ERROR_OBJECT (self, "ftruncate failed: %s", strerror (errno));
|
GST_ERROR_OBJECT (self, "ftruncate failed: %s", strerror (errno));
|
||||||
|
@ -102,17 +98,20 @@ gst_shm_allocator_alloc (GstAllocator * allocator, gsize size,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map R/W and keep it mapped to avoid useless mmap/munmap */
|
/* We use GST_FD_MEMORY_FLAG_KEEP_MAPPED, so make sure the first map is RW. */
|
||||||
if (!gst_memory_map (mem, &info, GST_MAP_READWRITE)) {
|
if (!gst_memory_map (mem, &info, GST_MAP_READWRITE)) {
|
||||||
GST_ERROR_OBJECT (self, "GstFdMemory map failed");
|
GST_ERROR_OBJECT (self, "GstFdMemory map failed");
|
||||||
close (fd);
|
gst_memory_unref (mem);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unmap will not really munmap(), we just
|
|
||||||
* need it to release the miniobject lock */
|
|
||||||
gst_memory_unmap (mem, &info);
|
gst_memory_unmap (mem, &info);
|
||||||
|
|
||||||
|
#ifdef HAVE_MEMFD_CREATE
|
||||||
|
/* Now that it's kept mapped RW, seal it for any future mapping. This ensures
|
||||||
|
* that other processes receiving this memfd won't be able to modify it. */
|
||||||
|
fcntl (fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_FUTURE_WRITE);
|
||||||
|
#endif
|
||||||
|
|
||||||
return mem;
|
return mem;
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in a new issue