mirror of
https://github.com/flatpak/flatpak.git
synced 2026-04-03 23:04:49 -04:00
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>
91 lines
3.0 KiB
C
91 lines
3.0 KiB
C
/*
|
|
* 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;
|
|
}
|