Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flatpak-spawn --host and tcsetpgrp issue #3697

Open
valentindavid opened this issue Jun 19, 2020 · 13 comments
Open

flatpak-spawn --host and tcsetpgrp issue #3697

valentindavid opened this issue Jun 19, 2020 · 13 comments

Comments

@valentindavid
Copy link
Contributor

Linux distribution and version

GNOME OS master

Flatpak version

Flatpak 1.4.3

Description of the problem

It seems bash has troubles to tcsetprg when spawning host bash with flatpak-spawn --host. This is unexpected since the in source code of HostCommand it should set the console right.

When using debug mode, we get the error:

F: ioctl(0, TIOCSCTTY, 0) failed: Operation not permitted

Maybe setsid and setpgid should not be called in child_setup_func from session-helper/flatpak-session-helper.c if data->set_tty.

Steps to reproduce

bash-5.0$ flatpak run --talk-name=org.freedesktop.Flatpak --command=bash org.freedesktop.Sdk//19.08
bash-5.0$ flatpak-spawn --host bash -i
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
bash-5.0$ 
@valentindavid
Copy link
Contributor Author

From the man page: If this terminal is already the controlling terminal of a different session group then the ioctl fails with EPERM, unless the caller is root (more precisely: has the CAP_SYS_ADMIN capability)

@valentindavid
Copy link
Contributor Author

I suppose ioctl TIOCSCTTY should be called from flatpak-spawn after flatpak-session-helper's child process has created the group.

@Erick555
Copy link
Contributor

Isn't this caused by TIOCSTI being blocked in flatpak?

@valentindavid
Copy link
Contributor Author

No the reason is the according to the man page of tcsetpgrp (called from bash):

ENOTTY
The calling process does not have a controlling terminal, or it has one but it is not described by fd, or, for tcsetpgrp(), this controlling terminal is no longer associated with the session of the calling process.

... And ioctl TIOCSCTTY called flatpak-session-helper:

If this terminal is already the controlling terminal of a different session group then the ioctl fails with EPERM, unless the caller is root (more precisely: has the CAP_SYS_ADMIN capability)

I do not think there is a way as a user to be able to move the terminal to control another session. And there is no way to move a process to another session. So I do not think it is possible.

We would need to create a pty and proxy it, GNU screen style.

@Erick555
Copy link
Contributor

Ok, I thought this is caused by sandbox because I see same message when I call bubblwrap with --new-session arg which is equivalent of what flatpak does to block TIOCSTI:

bwrap --bind / / --new-session bash
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell 

@valentindavid
Copy link
Contributor Author

Maybe the correct way to do it, is when calling flatpak, if it detects it is running in a tty, it should spawn a helper process. Maybe that registers to the main flatpak session helper. When flatpak-spawn tries to spawn a new process, instead of creating a process as a child of flatpak-spawn, it redirects it to the helper for the session. That helper will just take care of creating a new process, it will be automatically using the right terminal. Probably we can also setpgid the new process to the process group of flatpak-spawn so that CTRL-C is properly handled.

@akvadrako
Copy link

See also: #3285 and flatpak/flatpak-xdg-utils#15

@akvadrako
Copy link

When flatpak-spawn tries to spawn a new process, instead of creating a process as a child of flatpak-spawn, it redirects it to the helper for the session.

I'm not sure that'll work in many cases. What if a new pty is allocated in the sandbox, say by expect or gnome-terminal? Then when the user calls flatpak-spawn --host bash it won't work at all.

@akvadrako
Copy link

Here is a rough example for creating a pty, which I think is the correct approach: https://gist.github.com/akvadrako/24691578799e86c9d8303b854a5cf957

It doesn't handle redirected std{in,out,err} or window resizing.

@owtaylor
Copy link
Contributor

Point to some old code that does allocates a PTY and handles forwarding when using the org.freedesktop.Flatpak.Development.HostCommand interface. I forget at this point how complete it is - it may not handle resizing properly.

https://github.com/owtaylor/PurpleEgg/blob/master/common/host-command.c

@TingPing
Copy link
Member

I just want to add yet another example of a solution for this, used by gnome-builder.

https://gitlab.gnome.org/chergert/flatterm/-/blob/master/fp-vte-util.c

@1player
Copy link

1player commented Jun 1, 2022

Still encountering this issue. I've been trying to run emacs in a toolbox, and adding a TRAMP method to edit files on the host, through flatpak-spawn --host. This seems to work for simple file editing, but trying to exec programs or piping sudo to edit host files as superuser fails because of this exact issue.

Niche example, I know, but as more and more people try to run their IDE inside flatpak, this will be even more common.

@1player
Copy link

1player commented Jul 9, 2022

I've been working on a reimplementation of flatpak-spawn --host that handles this issue and a couple more: https://github.com/1player/host-spawn

Indeed the solution was to allocate a pty for the spawned process:

toolbox % flatpak-spawn --host bash -i
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
[sph@tranquility ~]$ exit

toolbox % ./host-spawn bash -i
[sph@tranquility ~]$

Contributions are welcome!

EDIT: The reason why I reimplemented flatpak-spawn is because doing it in Go is easier for me than hacking on C, but feel free to take inspiration from my code and fix the upstream logic. The code is in public domain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants