From 1b82bf2f9df06ee60d222b4fb45fe3490d05ef94 Mon Sep 17 00:00:00 2001 From: Simon McVittie 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 --- 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 . + * + * Authors: + * Alexander Larsson + */ + +#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 . + * + * Authors: + * Alexander Larsson + */ + +#include "config.h" + +#include "flatpak-utils-memfd-private.h" + +#include "valgrind-private.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 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,