From 1b82bf2f9df06ee60d222b4fb45fe3490d05ef94 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Mon, 11 Jan 2021 14:51:36 +0000
Subject: [PATCH] common: Move flatpak_buffer_to_sealed_memfd_or_tmpfile
 to its own file

We'll need this to use it in flatpak-portal without pulling the rest of
the common/ directory.

Signed-off-by: Simon McVittie <smcv@collabora.com>
---
 common/Makefile.am.inc               |  2 +
 common/flatpak-utils-memfd-private.h | 32 ++++++++++
 common/flatpak-utils-memfd.c         | 90 ++++++++++++++++++++++++++++
 common/flatpak-utils-private.h       |  1 +
 common/flatpak-utils.c               | 50 ----------------
 5 files changed, 125 insertions(+), 50 deletions(-)
 create mode 100644 common/flatpak-utils-memfd-private.h
 create mode 100644 common/flatpak-utils-memfd.c

diff --git a/common/Makefile.am.inc b/common/Makefile.am.inc
index 4844ab5..b681294 100644
--- a/common/Makefile.am.inc
+++ b/common/Makefile.am.inc
@@ -164,6 +164,8 @@ libflatpak_common_la_SOURCES = \
 	common/flatpak-transaction.c \
 	common/flatpak-transaction.h \
 	common/flatpak-utils-http-private.h \
+	common/flatpak-utils-memfd.c \
+        common/flatpak-utils-memfd-private.h \
 	common/flatpak-utils-http.c \
 	common/flatpak-utils-private.h \
 	common/flatpak-utils.c \
diff --git a/common/flatpak-utils-memfd-private.h b/common/flatpak-utils-memfd-private.h
new file mode 100644
index 0000000..65b550d
--- /dev/null
+++ b/common/flatpak-utils-memfd-private.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2014 Red Hat, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __FLATPAK_UTILS_MEMFD_H__
+#define __FLATPAK_UTILS_MEMFD_H__
+
+#include "libglnx/libglnx.h"
+
+gboolean flatpak_buffer_to_sealed_memfd_or_tmpfile (GLnxTmpfile *tmpf,
+                                                    const char  *name,
+                                                    const char  *str,
+                                                    size_t       len,
+                                                    GError     **error);
+
+#endif /* __FLATPAK_UTILS_MEMFD_H__ */
+
diff --git a/common/flatpak-utils-memfd.c b/common/flatpak-utils-memfd.c
new file mode 100644
index 0000000..9a0730f
--- /dev/null
+++ b/common/flatpak-utils-memfd.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2014 Red Hat, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+
+#include "flatpak-utils-memfd-private.h"
+
+#include "valgrind-private.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+
+/* If memfd_create() is available, generate a sealed memfd with contents of
+ * @str. Otherwise use an O_TMPFILE @tmpf in anonymous mode, write @str to
+ * @tmpf, and lseek() back to the start. See also similar uses in e.g.
+ * rpm-ostree for running dracut.
+ */
+gboolean
+flatpak_buffer_to_sealed_memfd_or_tmpfile (GLnxTmpfile *tmpf,
+                                           const char  *name,
+                                           const char  *str,
+                                           size_t       len,
+                                           GError     **error)
+{
+  if (len == -1)
+    len = strlen (str);
+  glnx_autofd int memfd = memfd_create (name, MFD_CLOEXEC | MFD_ALLOW_SEALING);
+  int fd; /* Unowned */
+  if (memfd != -1)
+    {
+      fd = memfd;
+    }
+  else
+    {
+      /* We use an anonymous fd (i.e. O_EXCL) since we don't want
+       * the target container to potentially be able to re-link it.
+       */
+      if (!G_IN_SET (errno, ENOSYS, EOPNOTSUPP))
+        return glnx_throw_errno_prefix (error, "memfd_create");
+      if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, tmpf, error))
+        return FALSE;
+      fd = tmpf->fd;
+    }
+  if (ftruncate (fd, len) < 0)
+    return glnx_throw_errno_prefix (error, "ftruncate");
+  if (glnx_loop_write (fd, str, len) < 0)
+    return glnx_throw_errno_prefix (error, "write");
+  if (lseek (fd, 0, SEEK_SET) < 0)
+    return glnx_throw_errno_prefix (error, "lseek");
+  if (memfd != -1)
+    {
+      /* Valgrind doesn't currently handle G_ADD_SEALS, so lets not seal when debugging... */
+      if ((!RUNNING_ON_VALGRIND) &&
+          fcntl (memfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL) < 0)
+        return glnx_throw_errno_prefix (error, "fcntl(F_ADD_SEALS)");
+      /* The other values can stay default */
+      tmpf->fd = glnx_steal_fd (&memfd);
+      tmpf->initialized = TRUE;
+    }
+  return TRUE;
+}
diff --git a/common/flatpak-utils-private.h b/common/flatpak-utils-private.h
index 1a92154..4c1ac61 100644
--- a/common/flatpak-utils-private.h
+++ b/common/flatpak-utils-private.h
@@ -32,6 +32,7 @@
 #include "flatpak-context-private.h"
 #include "flatpak-error.h"
 #include "flatpak-utils-http-private.h"
+#include "flatpak-utils-memfd-private.h"
 #include "flatpak-variant-private.h"
 #include "flatpak-dir-private.h"
 #include <ostree.h>
diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c
index 56cbb06..6901a62 100644
--- a/common/flatpak-utils.c
+++ b/common/flatpak-utils.c
@@ -1851,56 +1851,6 @@ flatpak_file_rename (GFile        *from,
   return TRUE;
 }
 
-/* If memfd_create() is available, generate a sealed memfd with contents of
- * @str. Otherwise use an O_TMPFILE @tmpf in anonymous mode, write @str to
- * @tmpf, and lseek() back to the start. See also similar uses in e.g.
- * rpm-ostree for running dracut.
- */
-gboolean
-flatpak_buffer_to_sealed_memfd_or_tmpfile (GLnxTmpfile *tmpf,
-                                           const char  *name,
-                                           const char  *str,
-                                           size_t       len,
-                                           GError     **error)
-{
-  if (len == -1)
-    len = strlen (str);
-  glnx_autofd int memfd = memfd_create (name, MFD_CLOEXEC | MFD_ALLOW_SEALING);
-  int fd; /* Unowned */
-  if (memfd != -1)
-    {
-      fd = memfd;
-    }
-  else
-    {
-      /* We use an anonymous fd (i.e. O_EXCL) since we don't want
-       * the target container to potentially be able to re-link it.
-       */
-      if (!G_IN_SET (errno, ENOSYS, EOPNOTSUPP))
-        return glnx_throw_errno_prefix (error, "memfd_create");
-      if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, tmpf, error))
-        return FALSE;
-      fd = tmpf->fd;
-    }
-  if (ftruncate (fd, len) < 0)
-    return glnx_throw_errno_prefix (error, "ftruncate");
-  if (glnx_loop_write (fd, str, len) < 0)
-    return glnx_throw_errno_prefix (error, "write");
-  if (lseek (fd, 0, SEEK_SET) < 0)
-    return glnx_throw_errno_prefix (error, "lseek");
-  if (memfd != -1)
-    {
-      /* Valgrind doesn't currently handle G_ADD_SEALS, so lets not seal when debugging... */
-      if ((!RUNNING_ON_VALGRIND) &&
-          fcntl (memfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL) < 0)
-        return glnx_throw_errno_prefix (error, "fcntl(F_ADD_SEALS)");
-      /* The other values can stay default */
-      tmpf->fd = glnx_steal_fd (&memfd);
-      tmpf->initialized = TRUE;
-    }
-  return TRUE;
-}
-
 gboolean
 flatpak_open_in_tmpdir_at (int             tmpdir_fd,
                            int             mode,
