This relaxes checks for apps. If Exec line defines only application
binary (+ arguments to app) then it may be defined without path. In that
case we require that the invoked binary path points to a file in
/usr/bin and basename matches to Exec line's first word.
Signed-off-by: Tomi Leppänen <tomi.leppanen@jolla.com>
Add --id option to specify identifier to use when asking sailjaild
whether the app should be sandboxed. It's not used for application
specific boosters or if the binary is already sailjail.
Signed-off-by: Tomi Leppänen <tomi.leppanen@jolla.com>
When sandboxed application booster has been selected via --application
or --auto-application options, there is no need to enforcing sandboxing
via injecting sailjail into launch argv.
Signed-off-by: Simo Piiroinen <simo.piiroinen@jolla.com>
When invoking via sandboxed application booster, application name
must be provided. As it usually is basename of the binary that is
going to be launched, using --application=binary-name creates
unnecessary repetition in Exec lines.
Add -A / --auto-application option that can be used when application
name matches executable basename.
Signed-off-by: Simo Piiroinen <simo.piiroinen@jolla.com>
When we include libgen.h, POSIX's basename will be used rather than
GNU's. Since we don't use the special functionalities of GNU's variant
anyway, this helps to compile it on POSIX-compliant libc's like Musl.
https://www.man7.org/linux/man-pages/man3/basename.3.html
Forces use of generic booster when it detects that application should be
sandboxed but it is not launched via sailjail already and prepends
sailjail argument.
Skips freeing of calloc'ed array.
Signed-off-by: Tomi Leppänen <tomi.leppanen@jolla.com>
Check before executing if the arguments don't contain sailjaild and the
if the app should be launched in a sandbox. In that case prepend the
arguments with sailjail.
This is not sufficient alone as the apps are launched via silica-qt5
booster which can't execute sailjail so this must be also taken into
account already before arguments reach booster.
Signed-off-by: Tomi Leppänen <tomi.leppanen@jolla.com>
When booster is executing in sandbox as an applicatiom booster, it
needs to verify that command line received from invoker matches
Exec line in application desktop file, application launch is allowed,
and permissions granted are as was expected at the time of booster
launch.
Provide booster-generic@.service that can be used for instantiating
sandboxed application boosters.
D-Bus ipc with sailjaild is modified version of similar code in
sailjailclient. The biggest difference is that this version uses
private connection via libdbus to avoid leaving stray dbus connections
or threads behind when transferring control to application code
without use of exec*() functions.
Remove cap_sys_ptrace from booster executable as makes it impossible
to run the booster within a no-new-privs sandbox.
Fix socket passing from booster instance to booster daemon so that it
works also when invoker is running in different namespace than booster
instance (invoker pid might be unresolvable).
Replace ad-hoc booster argument parsing with getopt_long().
Fix issues with argv handling: using const pointers for non-const
data, passing data by reference between objects that might have
different lifespans and never releasing the dynamically allocated
arrays.
Fix issues with env passing: duplicating invoker env at booster
side as-is can lead to problems like loss of customg session
bus socket address that has been set up by firejail.
If booster bumps into command read problems, bailout immediately
instead of relying on out-of sequence data possibly triggering
exit due to unknown commands.
As an enabler for sharing code between invoker (written in c) and
daemon (written in c++), modify Logger class used by c++ code so
that it is just a wrapper for logging functionality used by invoker.
Signed-off-by: Simo Piiroinen <simo.piiroinen@jolla.com>
Invoker and booster instance make up a process pair that are meant to exit
at the same time. To arrange this a) when invoker is about to exit, it sends
a terminating signal to booster instance, and b) when booster instance
exits, booster daemon sends a terminating signal to invoker. Overall this
has worked well enough - save some hiccups from potential race conditions -
but it is not compatible with setup where invoker and booster daemon are
running in different namespaces and sending signals is not possible.
There is already an unix domain socket that is kept open for the lifetime of
boosted application - used for transferring application information from
invoker to booster daemon during startup and exit status from booster daemon
to invoker at exit time. This socket can be utilized also for detecting when
peer process exits.
Normally when application (booster instance) exits, booster daemon receives
SIGCHLD, collects application exit reason, forwards it to invoker via
booster socket, and invoker then makes exit with the same exit status as
what application used.
Augment this by having booster daemon watch over booster sockets and
terminate booster instance upon eof on socket. This accomplishes that
application gets killed if/when invoker dies.
Additionally all booster instances are terminated if booster daemon exits
due to SIGTERM.
In general, instead of simply closing booster socket at each end at exit
time, an orderly disconnect is done via: shutdown write end of the socket,
read data until eof is received, then close socket. If this is accomplished
successfully within reasonable time limit, there is no need to send signals
- both peers know that the other end is going to make an appropriate exit.
Previously booster daemon and invoker made an attempt to reproduce
application getting killed by some signal such as as SIGSEGV also at the
invoker side. As this produces false positive crash reports and complicates
things (some of the signals are terminal and can't be handled in
asynchronous manner) this is no longer done - only standard TERM and KILL
signals are used for terminating peers and even then it is done as a last
resort.
Invoker signal handler used non async signal safe functions, those
have been removed.
To ease ad-hoc debugging, logging is automatically switched from syslog to
stderr when booster/invoker is executed from interactive command line.
Signed-off-by: Simo Piiroinen <simo.piiroinen@jolla.com>
Having all booster sockets reside at the same level in /run/user
directory structure makes it difficult to limit what boosters
sandboxed applications have access to.
Move socket files to booster specific sub-directories. And as an enabler
for sandboxed boosters, add another sub-directory level that can be used
for identifying application specific boosters.
As an example, silica-qt booster socket file path changes from
/run/user/UID/mapplauncherd/silica-qt5
to
/run/user/UID/mapplauncherd/_default/silica-qt5/socket
and sandboxed silica-qt5 booster for application APP would use
/run/user/UID/mapplauncherd/_APP/silica-qt5/socket
Signed-off-by: Simo Piiroinen <simo.piiroinen@jolla.com>
Comparing signed vs unsigned integers.
Unused static data.
Questionable variable declarations.
Const correctness issues.
Unchecked socket and pipe i/o.
Unchecked chdir() call.
String sender that silently skips null strings while protocol does
not make it possible for receiver to detect such omissions.
Signed-off-by: Simo Piiroinen <simo.piiroinen@jolla.com>
This allows packagers to set the proper directories to install stuff
too using CMAKE_INSTALL_PREFIX, CMAKE_INSTALL_LIBDIR, etc.
Also make installing systemd unit files optional, for systemd without
systemd, but enable them by default
This is mainly useful for non-glibc systems. Yes, systemd doesn't even run
on non-glibc systems, but elogind does and this way it links to both systemd
and elogind.
However due to switching the way we link to systemd, we now also make
sure systemd is actually installed on the system before we even try to
compile, thus preventing compiler errors when systemd isn't present.