mirror of
https://github.com/flatpak/flatpak.git
synced 2026-05-06 06:59:16 -04:00
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 d91660fe2a.
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.
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user