Skip to content

Disable the syscall sandbox for bitcoin-qt and remove gui-related syscalls #24758

Merged
laanwj merged 2 commits intobitcoin:masterfrom
maflcko:2204-gui-box-🌊
Apr 6, 2022

Hidden character warning

The head ref may contain hidden characters: "2204-gui-box-\ud83c\udf0a"
Merged

Disable the syscall sandbox for bitcoin-qt and remove gui-related syscalls #24758
laanwj merged 2 commits intobitcoin:masterfrom
maflcko:2204-gui-box-🌊

Conversation

@maflcko
Copy link
Member

@maflcko maflcko commented Apr 4, 2022

It is basically impossible (and a bit out of scope) for us to maintain a sandbox for the qt library. I am not sure if it is possible to only sandbox a few threads in a process, but I doubt this will add no practical benefit anyway, so I am disabling the sandbox for the whole bitcoin-qt process.

See also #24690 (comment)

@maflcko
Copy link
Member Author

maflcko commented Apr 4, 2022

On current master:

$ ./src/qt/bitcoin-qt -sandbox=log-and-abort 
ERROR: The syscall "memfd_create" (syscall number 319) is not allowed by the syscall sandbox in thread "main". Please report.
terminate called without an active exception
Aborted (core dumped)

With this pull:

All good

@hebasto
Copy link
Member

hebasto commented Apr 4, 2022

Concept ACK.

@laanwj
Copy link
Member

laanwj commented Apr 4, 2022

Concept ACK.

I am not sure if it is possible to only sandbox a few threads in a process, but I doubt this will add no practical benefit anyway

This is definitely possible. It's why there are different syscall profiles in the first place. It makes sense to sandbox threads that interface with the outside world e.g. the network thread, or RPC threads. It doesn't make much sense to sandbox the GUI thread as it interfaces with the user.

@maflcko
Copy link
Member Author

maflcko commented Apr 4, 2022

Ok. I believe, currently the syscall sandbox in Bitcoin Core is set up so that it registers as early as possible (thus locking down all threads with the "default sandbox") and then later locking down each newly created thread with additional restrictions.

To work around this with the GUI, the initial lock-down for the main thread would need to be skipped. Presumably the restriction on the main thread, once it gets renamed to shutoff as well.

I am not sure if it is worth it to make those changes, give that multiprocess will fix this as well.

Copy link

@vincenzopalazzo vincenzopalazzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK

@ryanofsky
Copy link
Contributor

I am not sure if it is possible to only sandbox a few threads in a process

Maybe I'm misreading, but I don't understand this comment. The whole design of practicalswift's sandboxing implementation is premised on allowing specific threads to make specific syscalls, so obviously this is possible and we're already doing it. If there are cases where the same thread in bitcoind is doing something different when a GUI is present, these seem like bugs that should be fixed. Or I guess I don't understand where these cases would ever be expected.

I do understand that the main GUI thread is doing a lot of things out of our control and may be easier not to sandbox, though.

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading earlier discussion it seems like problems are in fact happening on the main gui thread not other threads.

It does seem like instead of disabling sandboxing entirely, it would be better to just not sandbox the gui thread, or allow extra syscalls on the gui thread. But maybe this is more complicated to implement.

Concept ACK in any case, since I think I understand this now, and Code review ACK 33335a3c6eab616823a380241b58495b88b89e1d

@jarolrod
Copy link
Contributor

jarolrod commented Apr 5, 2022

concept ack

@laanwj
Copy link
Member

laanwj commented Apr 5, 2022

It does seem like instead of disabling sandboxing entirely, it would be better to just not sandbox the gui thread, or allow extra syscalls on the gui thread. But maybe this is more complicated to implement.

The point is that we cannot have a complete view of what the GUI thread does. By nature it calls into the operating system to do things like rendering. In the worst case this involves, say, proprietary video drivers. Or special constructions for input devices. Just adding syscalls when they come up is a bottomless pit of despair.

This is a fundamental problem with system-call based sandboxing. It's a layer violation. Sandboxing other threads also suffers from this problem, but less. E.g., libraries that are dynamically linked (say, glibc) may change the system calls they use at any point (this happens pretty often). GUI is just especially bad in this regard.

I agree that the other threads could still be sandboxed, ideally, because even if they do have callbacks to Qt code they shouldn't be doing any rendering or input handling.

To work around this with the GUI, the initial lock-down for the main thread would need to be skipped. Presumably the restriction on the main thread, once it gets renamed to shutoff as well.

Sounds like a good solution to me. The difference would be that part of the initialization process wouldn't be sandboxed either. This is fine, sandboxing is mostly interesting for threads that communicate with anything untrusted.

@laanwj
Copy link
Member

laanwj commented Apr 5, 2022

This is a fundamental problem with system-call based sandboxing. It's a layer violation.

As an aside, one project that attempts to work around these kind of fragility of syscall sandboxing, in the Linux kernel, is https://landlock.io/ . It groups certain logical actions as being allowed or not instead of micro-managing syscalls. But it's still under heavy development I don't think it makes sense to start using that at this point.

Also, even then the GUI is probably… weird

@laanwj
Copy link
Member

laanwj commented Apr 5, 2022

Code review ACK fa45bb70b83cb57967bc3a57d7da0f972facb864
Code review ACK fabdf9f

Ostensibly you could still do SetSyscallSandboxPolicy(SyscallSandboxPolicy::INITIALIZATION); in the core thread started in BitcoinApplication::startThread() (InitExecutor, if I follow the code correctly). It handles the larger part of the initialization/shutdown process. But it doesn't matter too much.

MarcoFalke added 2 commits April 5, 2022 13:29
* Revert "util: Add inotify_rm_watch to syscall sandbox (AllowFileSystem)"
  This reverts commit f05a4cd.

* Revert "util: add linkat to syscall sandbox (AllowFileSystem)"
  This reverts commit 9809db3.
@laanwj laanwj merged commit c5c4fb3 into bitcoin:master Apr 6, 2022
@maflcko maflcko deleted the 2204-gui-box-🌊 branch April 6, 2022 09:59
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Apr 6, 2022
@bitcoin bitcoin locked and limited conversation to collaborators Apr 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants