From 8bdb2fa004e15a9bc0468a334c6f4986d5c33b98 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Tue, 19 Nov 2019 21:33:37 +0000 Subject: [PATCH] system-helper: fix busyloop in revokefs writer process After an unprivileged client calls GetRevokefsFd(), the `revokefs-fuse --backend` process busyloops as follows: poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}], 2, -1) = 1 ([{fd=4, revents=POLLIN}]) Here is the command line for this process: revokefs-fuse --backend --socket=3 --exit-with-fd=4 /var/lib/flatpak/repo/tmp/flatpak-cache-JBUHB0 The intention here is to poll() until fd 3 is readable (at which point the writer process serves a client request and writes back a response, synchronously) or fd 4 encounters an error. fd 4 is meant to be one side of a pipe that the system helper holds the other end of; when the pipe is broken, the system helper must have gone away, and the `revokefs-fuse --backend` process treats this as a signal to exit. However, fd 4 is not a pipe. In fact, it is the dirfd for the target directory: root@camille:/var/roothome# ls -l /proc/31717/fd total 0 lr-x------ 1 wjt wjt 64 Nov 19 21:21 0 -> /dev/null lrwx------ 1 wjt wjt 64 Nov 19 21:21 1 -> /dev/pts/1 lrwx------ 1 wjt wjt 64 Nov 19 21:21 2 -> /dev/pts/1 lrwx------ 1 wjt wjt 64 Nov 19 21:21 3 -> 'socket:[2558007]' lr-x------ 1 wjt wjt 64 Nov 19 21:21 4 -> /var/lib/flatpak/repo/tmp/flatpak-cache-JBUHB0 This is because revokefs_fuse_backend_child_setup() erroneously closes fd 4 before the `revokefs-fuse --backend` process is exec()d. This regressed in d91660fe2a4a508479be922140b112e7e8809180. Fix this by only closing fds 5 and above. With this change, we see the expected set of open file descriptors: root@camille:/var/roothome# ls -l /proc/32493/fd total 0 lr-x------ 1 wjt wjt 64 Nov 19 21:24 0 -> /dev/null lrwx------ 1 wjt wjt 64 Nov 19 21:24 1 -> /dev/pts/1 lrwx------ 1 wjt wjt 64 Nov 19 21:24 2 -> /dev/pts/1 lrwx------ 1 wjt wjt 64 Nov 19 21:24 3 -> 'socket:[2552594]' lr-x------ 1 wjt wjt 64 Nov 19 21:24 4 -> 'pipe:[2552596]' lr-x------ 1 wjt wjt 64 Nov 19 21:24 5 -> /var/lib/flatpak/repo/tmp/flatpak-cache-JBUHB0 Fixes #2882. --- system-helper/flatpak-system-helper.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/system-helper/flatpak-system-helper.c b/system-helper/flatpak-system-helper.c index b6b484a8..c6be8a66 100644 --- a/system-helper/flatpak-system-helper.c +++ b/system-helper/flatpak-system-helper.c @@ -1467,9 +1467,10 @@ revokefs_fuse_backend_child_setup (gpointer user_data) { struct passwd *passwd = user_data; - /* We use 4 instead of 3 here, because fd 3 is the inerited socket - and got dup2() into place before this by GSubprocess */ - flatpak_close_fds_workaround (4); + /* We use 5 instead of 3 here, because fd 3 is the inherited SOCK_SEQPACKET + * socket and fd 4 is the --close-with-fd pipe; both were dup2()'d into place + * before this by GSubprocess */ + flatpak_close_fds_workaround (5); if (setgid (passwd->pw_gid) == -1) {