Skip to content
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

kodi: linux use MFD_NOEXEC_SEAL for shared memory #8430

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
From f4828906ec8617a47a7af76ae3953d8dc306865e Mon Sep 17 00:00:00 2001
From: Rudi Heitbaum <[email protected]>
Date: Fri, 14 Jul 2023 10:25:10 +0000
Subject: [PATCH] linux use MFD_NOEXEC_SEAL for shared memory

ref: https://lore.kernel.org/lkml/[email protected]/

The new MFD_NOEXEC_SEAL and MFD_EXEC flags allows application to set
executable bit at creation time (memfd_create).

When MFD_NOEXEC_SEAL is set, memfd is created without executable bit
(mode:0666), and sealed with F_SEAL_EXEC, so it can't be chmod to be
executable (mode: 0777) after creation.

When MFD_EXEC flag is set, memfd is created with executable bit
(mode:0777), this is the same as the old behavior of memfd_create.

Signed-off-by: Rudi Heitbaum <[email protected]>
---
xbmc/platform/posix/utils/SharedMemory.cpp | 14 +++++++++++---
xbmc/utils/UDMABufferObject.cpp | 12 +++++++++++-
2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/xbmc/platform/posix/utils/SharedMemory.cpp b/xbmc/platform/posix/utils/SharedMemory.cpp
index 6c1318e936..115d3d41ce 100644
--- a/xbmc/platform/posix/utils/SharedMemory.cpp
+++ b/xbmc/platform/posix/utils/SharedMemory.cpp
@@ -15,6 +15,9 @@
#if defined(HAVE_LINUX_MEMFD)
#include <linux/memfd.h>
#include <sys/syscall.h>
+#ifndef MFD_NOEXEC_SEAL
+#define MFD_NOEXEC_SEAL 0x0008U
+#endif
#endif

#include <cerrno>
@@ -62,8 +65,13 @@ CFileHandle CSharedMemory::OpenMemfd()
{
#if defined(SYS_memfd_create) && defined(HAVE_LINUX_MEMFD)
// This is specific to Linux >= 3.17, but preferred over shm_create if available
- // because it is race-free
- int fd = syscall(SYS_memfd_create, "kodi", MFD_CLOEXEC);
+ // because it is race-free. Since linux >= 6.3 create with the MFD_NOEXEC_SEAL flag.
+ int fd = syscall(SYS_memfd_create, "kodi", MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL);
+ if (fd < 0)
+ {
+ // retry creating fd without MFD_NOEXEC_SEAL to support linux < 6.3
+ fd = syscall(SYS_memfd_create, "kodi", MFD_CLOEXEC | MFD_ALLOW_SEALING);
+ }
if (fd < 0)
{
throw std::system_error(errno, std::generic_category(), "memfd_create");
@@ -115,4 +123,4 @@ CFileHandle CSharedMemory::OpenShm()
unlink(tmpFilename.c_str());

return fd;
-}
\ No newline at end of file
+}
diff --git a/xbmc/utils/UDMABufferObject.cpp b/xbmc/utils/UDMABufferObject.cpp
index 2b8336bcea..1af03428e6 100644
--- a/xbmc/utils/UDMABufferObject.cpp
+++ b/xbmc/utils/UDMABufferObject.cpp
@@ -20,6 +20,10 @@

#include "PlatformDefs.h"

+#ifndef MFD_NOEXEC_SEAL
+#define MFD_NOEXEC_SEAL 0x0008U
+#endif
+
namespace
{

@@ -95,7 +99,13 @@ bool CUDMABufferObject::CreateBufferObject(uint64_t size)
// Must be rounded to the system page size
m_size = RoundUp(size, PAGESIZE);

- m_memfd = memfd_create("kodi", MFD_CLOEXEC | MFD_ALLOW_SEALING);
+ // Since linux >= 6.3 create with the MFD_NOEXEC_SEAL flag.
+ m_memfd = memfd_create("kodi", MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL);
+ if (m_memfd < 0)
+ {
+ // retry creating m_memfd without MFD_NOEXEC_SEAL to support linux < 6.3
+ m_memfd = memfd_create("kodi", MFD_CLOEXEC | MFD_ALLOW_SEALING);
+ }
if (m_memfd < 0)
{
CLog::Log(LOGERROR, "CUDMABufferObject::{} - memfd_create failed: {}", __FUNCTION__,
--
2.34.1