strace-ing an AppImage
4 minutes read •
A little while ago I was asked to run an experiment involving a drone’s flight controller and its serial telemetry capabilities over various ports. I was specifically looking to see what the maximum stable baudrate was for the USB serial connection. Since this task required sending and receiving MAVLink messages, which is a binary protocol, the simplest way was to hook it up to QGroundControl and see what breaks.
QGroundControl usually automatically detects flight controllers when they are plugged in, but it’s also possible to disable this behaviour and specify the serial port and baudrate to use. Though I wasn’t one hundred percent sure it wasn’t trying to be too helpful and automatically lowering the baudrate in case of a garbled connection.
So I wanted to strace the application to see what sort of calls it makes to the kernel to configure the TTY. Should be simple, right?
Simple is dead, and we killed it.
AppImages and you
The official way to run QGroundControl on Linux is via the officially distributed AppImage. AppImages work by bundling (almost) all userspace dependencies that the application is built against, which then get transparently mounted to the system. And it’s this last part that’s the issue here.
AppImages mount their contents via FUSE, specifically by calling fusermount. And because mounting filesystems usually requires superuser privileges, fusermount has a very special bit set on it.
That s in the fourth column means this binary makes use of the kernel’s setuid feature. We can also verify this by calling file on the executable.
This makes the application very scary.
Setuid and security
The expression setuid is relatively easy to make sense of, it sets a userid somehow. But how and what does it set?
It’s how sudo works. The setuid bit tells the kernel to run the executable file as its owner. And since the owner of fusermount is root, it means this application (like sudo) runs with superuser permissions, no matter what user launches it.
There have been countless privilege escalation vulnerabilities thanks to this kernel capability. A vulnerability in anything that’s been blessed with setuid root could spell doom for a system. And this is why we fail to trace our target. Imagine what an attacker could surmise from a system trace of something launched as root. So strace (and ptrace for that matter) completely disables processing setuid.
Let’s say we wanted to strace sudo. It would fail to escalate to root and then collapse.
So we need to escalate permissions manually.
The setuid we have at home
If we run the trace under sudo, we run into an old classic.

Fair enough, thankfully if we read the manual of strace, there is a function to drop to a different user account for the traced program. And it doesn’t even disable setuid again!
We’re i-!
Wait, something’s not quite right yet.

The flight controller connected fine behind the warning, so I’ll just dismiss it. But what’s this now?

I already did this setup. Why am I being prompted again? And where is my serial device configuration?
Oh no…
Changing Environment
When you switch users through strace -u the environment variables don’t get switched back to your user’s.
QGroundControl doesn’t complain because the UID isn’t 0, but the environment variables still tell it to read its configuration from /root instead of my home directory. There doesn’t seem to be an official way for strace to restore the environment, but we can ask sudo not to change it in the first place.
But $USER is still root, because even with the -E flag, sudo still changes a few values. But we can disable these changes too, by adding --preserve-env multiple times. At this point I’d recommend that you manually diff the output of just bare env and env launched through this mess of utilities, but for me I still had to specify LOGNAME, USER, and PATH.
And with all this finished, we are finally victorious.
For the record, I couldn’t tell if QGroundControl would autobaud on failure, because the flight controller could take the highest option of 4000000 baud without an issue.
Comments
You can comment on this blog post by publicly replying to this post using a Mastodon or other ActivityPub/Fediverse account. Known non-private replies are displayed below.