mirror of
https://github.com/flatpak/flatpak.git
synced 2026-04-02 22:34:25 -04:00
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. [Part of a 1.2.x backport of GHSA-4ppf-fxf6-vxg2 for Debian 10.] Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
committed by
Alexander Larsson
parent
388a6044d0
commit
1b82bf2f9d
@@ -99,6 +99,8 @@ libflatpak_common_la_SOURCES = \
|
||||
common/flatpak-utils.c \
|
||||
common/flatpak-utils-http.c \
|
||||
common/flatpak-utils-http-private.h \
|
||||
common/flatpak-utils-memfd.c \
|
||||
common/flatpak-utils-memfd-private.h \
|
||||
common/flatpak-utils-private.h \
|
||||
common/flatpak-chain-input-stream.c \
|
||||
common/flatpak-chain-input-stream-private.h \
|
||||
|
||||
32
common/flatpak-utils-memfd-private.h
Normal file
32
common/flatpak-utils-memfd-private.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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__ */
|
||||
90
common/flatpak-utils-memfd.c
Normal file
90
common/flatpak-utils-memfd.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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 <ostree.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
|
||||
@@ -2281,56 +2281,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,
|
||||
|
||||
Reference in New Issue
Block a user