After looking closely at this, I realized that we've been running
all the service processes under separate user accounts even though
there's actually no need to.
Since we already use pledge() and unveil() to limit the scope and
access of these programs, separating them to another UID doesn't
achieve anything meaningful. So let's bring them back to the "anon"
user account and simplify things.
Programs affected:
- ImageDecoder
- RequestServer
- WebContent
- WebSocket
Longer term, I'd like for all of these to get spawned for the current
desktop user somehow, possibly by some kind of session manager, or
perhaps by the Browser program itself. But for now they remain under
SystemServer's control.
The current ProtocolServer was really only used for requests, and with
the recent introduction of the WebSocket service, long-lasting
connections with another server are not part of it. To better reflect
this, this commit renames it to RequestServer.
This commit also changes the existing 'protocol' portal to 'request',
the existing 'protocol' user and group to 'request', and most mentions
of the 'download' aspect of the request to 'request' when relevant, to
make everything consistent across the system.
Note that LibProtocol still exists as-is, but the more generic Client
class and the more specific Download class have both been renamed to a
more accurate RequestClient and Request to match the new names.
This commit only change names, not behaviors.
The WebSocket service isolates communication with a WebSocket to its
own isolated process. Similar to other isolating services, it has its
own user and group.
This patch adds SymbolServer, a service daemon that provides
symbolication of ELF binaries. It has a very simple IPC API at the
moment that only turns addresses into symbol names.
This can be used to implement symbolication without having to do
in-process ELF parsing yourself. :^)
To keep track of ongoing terminal sessions, we now have a sort-of
traditional /var/run/utmp file, like other Unix systems.
Unlike other Unix systems however, ours is of course JSON. :^)
The /bin/utmpupdate program is used to update the file, which is
not writable by regular user accounts. This helper program is
set-GID "utmp".
The new ImageDecoder service (available for members of "image" via
/tmp/portal/image) allows you to decode images in a separate process.
This will allow programs to confidently load untrusted images, since
the bulk of the security concerns are sandboxed to a separate process.
The only API right now is a synchronous IPC DecodeImage() call that
takes a shbuf with encoded image data and returns a shared buffer and
metadata for the decoded image.
It also comes with a very simple library for interfacing with the
ImageDecoder service: LibImageDecoderClient. The name is a bit of a
mouthful but I guess we can rename it later if we think of something
nicer to call it.
There's obviously a bit of overhead to spawning a separate process
for every image decode, so this is mostly only appropriate for
untrusted images (e.g stuff downloaded from the web) and not necessary
for trusted local images (e.g stuff in /res)
The "WebContent" service provides a very restricted instance of LibWeb
running as an unprivileged user account. This will be used to implement
process separation in Browser, among other things.
This first cut of the service only spawns a single WebContent process
when someone connects to /tmp/portal/webcontent. We will soon switch
this over to spawning a new process for each connection.
Since this feature is very immature, we'll be bringing it up inside of
Demos/WebView as a separate demo program. Eventually this will become
a reusable widget that anyone can embed and easily get out-of-process
web content in their GUI.
This is pretty, pretty cool! :^)
We were getting a little overly memey in some places, so let's scale
things back to business-casual.
Informal language is fine in comments, commits and debug logs,
but let's keep the runtime nice and presentable. :^)
This commit moves the clipboard from WindowServer into a new Clipboard
service program. Clipboard runs as the unprivileged "clipboard" user
and with a much tighter pledge than WindowServer.
To keep things working as before, all GUI::Application users now make
a connection to Clipboard after making the connection to WindowServer.
It could be interesting to connect to Clipboard on demand, but right
now that would necessitate expanding every GUI app's pledge to include
"unix" and also unveiling the clipboard portal, which I prefer not to.
This patch adds NotificationServer, which runs as the "notify" user
and provides an IPC API for desktop notifications.
LibGUI gains the GUI::Notification class for showing notifications.
NotificationServer is spawned on demand and will unspawn after
dimissing all visible notifications. :^)
Finally, this also comes with a small /bin/notify utility.
This was actually rather painless and straightforward. WindowServer now
runs as the "window" user. Users in the "window" group can connect to
it via the socket in /tmp/portal/window as usual.
This is probably not the final design we'll want for this, but for now
let's run the HTTP client code as a separate user to reduce exposure
for the standard "anon" user account.
Note that "protocol" is also added to the "lookup" group, in order to
allow ProtocolServer to contact LookupServer for DNS requests.
LookupServer now runs as lookup:lookup, allowing connections from other
members of the "lookup" group.
This is enforced through file system permissions by having the service
socket (/tmp/portal/lookup) be mode 0660.
Now the LookupServer program can't overwrite other people's files if it
starts misbehaving. That's pretty cool :^)