Plasma Wayland relocatability

Harald Sitter sitter at kde.org
Tue Feb 21 11:48:37 UTC 2017


Hola!

For a while now I've been chipping away at making Plasma relocatable
with the purpose of putting Plasma in a snap package (same applies to
appimage FWIW, flatpak uses a static path), which happens to mount the
bundle content under `/snap/$name/$REV/` meaning there is a severe
need to be to have relocatable binaries.

Simply put if I install to `/foo` and then move that dir to `/bar` it
should continue to work fine.

Right now it doesn't work because we have a veritable chain of
hard-compiled paths.

Simplified start-chain for reference

```
startplasmacompositor (sh)
-> bunch of helpers binaries
-| kwin_wayland (wayland compositor)
--> xwayland
--| startplasma (sh)
---> start_kdeinit_wrapper
----> start_kdeinit
-----> kdeinit5
------> klauncher
------| ksmserver
-------> session autostart/restore etc
-------| kded5
-------| plasma
--------> kactivitymanagerd
```

# startplasmacompositor

- Resolves qdbus via qtpaths which is not relocatable, that's not
really our fault and probably not too easy to solve or even worth it.
Finding qdbus reliably has been a long standing problem unfortunately.
 - Hard-compiles the kwin_wayland path. I think this is actually
security relevant and necessary. startplasmacompsitor would already
have a user environment, so it could have a bad PATH with a
kwin_wayland ontop of the actual kwin_wayland. I'd actually find it
better if this script got replaced by kwin_wayland or a C/C++ helper.
If /bin/sh is a symlink to /bin/bash the environment easily can be
full of rubbish from the user session which may or may not be seeking
to exploit kwin.
- Hard-compiles the startplasma path

# xwayland

Xwayland is simply not relocatable as xkbcomp's full path is hard-compiled.

# startplasma

- Actually executes qdbus from PATH where startplasmacompositor took
great care to grab it from qpaths, that seems silly. I am thinking
either both should run from PATH or none.
- Hard-compiles start_kdeinit_wrapper
- Hard-compiles ksmserver

# kinit

Oh boy, this is my new favorite thing.
So, kinit is actually doing 4 glorious forks.

start_kdeinit_wrapper starts start_kdeinit. Why does it do that you ask.

Qutoing code comment
> The start_kdeinit wrapper is setuid, which means some shell variables like
> LD_LIBRARY_PATH get unset before it's launched.

Aha!

> $ ls -lah /usr/lib/x86_64-linux-gnu/libexec/kf5/start_kdeinit
> -rwxr-xr-x 1 root root 11K Feb 14 18:22 /usr/lib/x86_64-linux-gnu/libexec/kf5/start_kdeinit

Well, that's a lie. Probably incorrectly ported somewhere along the line.

But I hear you asking what the point of start_kdeinit is. Comment again:

> Prevent getting killed by bad heuristic in Linux OOM-killer.
> This wrapper decreases the chance OOM killer kills it (or its children,
> namely kdeinit)

Yeah, that's not really working now is it.

> $ cat /proc/`pidof kdeinit5`/oom_*
> 0
> 1
> 0

More importantly this makes no sense. See reference table from above,
everything depends on kwin_wayland, kwin_wayland doesn't OOM adj, so
whether or not kdeinit is OOM adjusted is fairly irrelevant as kwin
might get murdered causing everything to get murdered. (Xorg isn't
decreased either, so same there).

But let's take step back here. start_kdeinit wants to OOM adjust so
that it doesn't get murdered. How old is this code?
In kernel 2.6.39 already the score is documented as a value of
badness. Over simplified: the more memory a process uses, the worse
its score, the more likely is it to get killed during OOM handling.
So, how in the world would kdeinit5 have such a bad score that it gets murderd?
This entire construct makes no sense to me and should be dropped, the
way I see it this is overengineered nonsense.

# kdeinit5

- Hard-compiles path to klauncher
- Should be dropped in favor of dbus activation or systemd socket
activation (slightly out of scope, I know ;))

# ksmserver

Starting here things seem to largely not be hardcoded anymore. Rejoice!

# conclusion

- startkdeinit is making me angry
- We have a real problem with libexec. 90% of hardcompiled paths I
tend to find are frameworks things that need to run something from
libexec. Hardcompiling seems like a massive hack for finding where
your libexec is. I am not sure how to best resolve this, but I'd
imagine QStandardPaths could do with an extension to handle paths
within library paths.

e.g. QStandardPaths::findLibExectuable("klauncher", "libexec", QStringList());
which would iter qapp->libraryPaths() and LD_LIBRARY_PATH for
directory "libexec" and then look for exectuable klauncher in the
found libexecs.

[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/proc.txt?id=refs/tags/v2.6.39#n1276

HS


More information about the Plasma-devel mailing list