mirror of
https://github.com/flatpak/flatpak.git
synced 2026-04-13 19:37:53 -04:00
revokefs-fuse: Add --with-exit-fd arg to monitor parent process's exit
This is necessary so as to not leave the revokefs backend around when the system-helper exits abruptly (e.g. OOM killer). It would be a vulnerability if revokefs backend continues to live even after the system-helper is killed as it might lead to write access to the underlying directory. Closes: #2657 Approved by: alexlarsson
This commit is contained in:
@@ -444,6 +444,7 @@ usage (const char *progname)
|
||||
" -h --help print help\n"
|
||||
" --socket=fd Pass in the socket fd\n"
|
||||
" --backend Run the backend instead of fuse\n"
|
||||
" --exit-with-fd=fd With --backend, exit when the given file descriptor is closed\n"
|
||||
"\n", progname);
|
||||
}
|
||||
|
||||
@@ -478,6 +479,7 @@ revokefs_opt_proc (void *data,
|
||||
|
||||
struct revokefs_config {
|
||||
int socket_fd;
|
||||
int exit_with_fd;
|
||||
int backend;
|
||||
};
|
||||
|
||||
@@ -485,6 +487,7 @@ struct revokefs_config {
|
||||
|
||||
static struct fuse_opt revokefs_opts[] = {
|
||||
REVOKEFS_OPT ("--socket=%i", socket_fd, -1),
|
||||
REVOKEFS_OPT ("--exit-with-fd=%i", exit_with_fd, -1),
|
||||
REVOKEFS_OPT ("--backend", backend, 1),
|
||||
|
||||
FUSE_OPT_KEY ("-h", KEY_HELP),
|
||||
@@ -497,7 +500,7 @@ main (int argc, char *argv[])
|
||||
{
|
||||
struct fuse_args args = FUSE_ARGS_INIT (argc, argv);
|
||||
int res;
|
||||
struct revokefs_config conf = { -1 };
|
||||
struct revokefs_config conf = { -1, -1 };
|
||||
|
||||
res = fuse_opt_parse (&args, &conf, revokefs_opts, revokefs_opt_proc);
|
||||
if (res != 0)
|
||||
@@ -529,7 +532,7 @@ main (int argc, char *argv[])
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
do_writer (basefd, conf.socket_fd);
|
||||
do_writer (basefd, conf.socket_fd, conf.exit_with_fd);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
@@ -559,7 +562,7 @@ main (int argc, char *argv[])
|
||||
{
|
||||
/* writer process */
|
||||
close (sockets[0]);
|
||||
do_writer (basefd, sockets[1]);
|
||||
do_writer (basefd, sockets[1], -1);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <sys/xattr.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
#include <fuse.h>
|
||||
|
||||
#include <glib.h>
|
||||
@@ -759,7 +760,8 @@ request_access (int writer_socket, const char *path, int mode)
|
||||
|
||||
void
|
||||
do_writer (int basefd_arg,
|
||||
int fuse_socket)
|
||||
int fuse_socket,
|
||||
int exit_with_fd)
|
||||
{
|
||||
guchar request_buffer[MAX_REQUEST_SIZE];
|
||||
RevokefsRequest *request = (RevokefsRequest *)&request_buffer;
|
||||
@@ -773,6 +775,27 @@ do_writer (int basefd_arg,
|
||||
{
|
||||
ssize_t data_size, size;
|
||||
ssize_t response_data_size, response_size, written_size;
|
||||
int res;
|
||||
struct pollfd pollfds[2] = {
|
||||
{fuse_socket, POLLIN, 0 },
|
||||
{exit_with_fd, POLLIN, 0 },
|
||||
};
|
||||
|
||||
res = poll(pollfds, exit_with_fd >= 0 ? 2 : 1, -1);
|
||||
if (res < 0)
|
||||
{
|
||||
perror ("Got error polling sockets: ");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (exit_with_fd >= 0 && (pollfds[1].revents & (POLLERR|POLLHUP)) != 0)
|
||||
{
|
||||
g_printerr ("Received EOF on exit-with-fd argument");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (pollfds[0].revents & POLLIN == 0)
|
||||
continue;
|
||||
|
||||
size = TEMP_FAILURE_RETRY (read (fuse_socket, request_buffer, sizeof (request_buffer)));
|
||||
if (size == -1)
|
||||
|
||||
@@ -39,7 +39,7 @@ int request_fsync (int writer_socket, int fd);
|
||||
int request_close (int writer_socket, int fd);
|
||||
int request_access (int writer_socket, const char *path, int mode);
|
||||
|
||||
void do_writer (int basefd, int socket);
|
||||
void do_writer (int basefd, int socket, int exit_with_fd);
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -72,6 +72,8 @@ typedef struct
|
||||
uid_t uid; /* uid of the client initiating the pull */
|
||||
|
||||
gint client_socket; /* fd that is send back to the client for spawning revoke-fuse */
|
||||
gint backend_exit_socket; /* write end of a pipe which helps terminating revokefs backend if
|
||||
system helper exits abruptly */
|
||||
|
||||
gchar *src_dir; /* source directory containing the actual child repo */
|
||||
gchar *unique_name;
|
||||
@@ -131,6 +133,7 @@ ongoing_pull_free (OngoingPull *pull)
|
||||
g_clear_pointer (&pull->src_dir, g_free);
|
||||
g_clear_pointer (&pull->unique_name, g_free);
|
||||
close (pull->client_socket);
|
||||
close (pull->backend_exit_socket);
|
||||
|
||||
g_slice_free (OngoingPull, pull);
|
||||
}
|
||||
@@ -1497,7 +1500,7 @@ ongoing_pull_new (FlatpakSystemHelper *object,
|
||||
GDBusConnection *connection = g_dbus_method_invocation_get_connection (invocation);
|
||||
g_autoptr(OngoingPull) pull = NULL;
|
||||
g_autoptr(GSubprocessLauncher) launcher = NULL;
|
||||
int sockets[2];
|
||||
int sockets[2], exit_sockets[2];
|
||||
|
||||
pull = g_slice_new0 (OngoingPull);
|
||||
pull->object = object;
|
||||
@@ -1521,17 +1524,30 @@ ongoing_pull_new (FlatpakSystemHelper *object,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pipe2 (exit_sockets, O_CLOEXEC) == -1)
|
||||
{
|
||||
glnx_throw_errno_prefix (error, "Failed to create a pipe");
|
||||
close (sockets[0]);
|
||||
close (sockets[1]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
|
||||
g_subprocess_launcher_set_child_setup (launcher, revokefs_fuse_backend_child_setup, passwd, NULL);
|
||||
g_subprocess_launcher_take_fd (launcher, sockets[0], 3);
|
||||
fcntl (sockets[1], F_SETFD, FD_CLOEXEC);
|
||||
pull->client_socket = sockets[1];
|
||||
|
||||
g_subprocess_launcher_take_fd (launcher, exit_sockets[0], 4);
|
||||
pull->backend_exit_socket = exit_sockets[1];
|
||||
|
||||
pull->revokefs_backend = g_subprocess_launcher_spawn (launcher,
|
||||
error,
|
||||
"revokefs-fuse",
|
||||
"--backend",
|
||||
"--socket=3", src, NULL);
|
||||
"--socket=3",
|
||||
"--exit-with-fd=4",
|
||||
src, NULL);
|
||||
if (pull->revokefs_backend == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user