Sandboxing an application
For this weeks issue I decided to do some investigative journalism on the topic of app sandboxing. How would one go about fixing an app which does not behave well in the sandbox? Just for the study purposes I decided to break (and then fix) one app which is familiar to all of you: jolla-gallery.
Breaking the app
In order to emulate a situation where we have an app which doesn’t work in the sandbox, I removed all of the permissions from jolla-gallery.desktop. The broken X-Sailjail
section looked like this:
[X-Sailjail]
Permissions=
OrganizationName=com.jolla
ApplicationName=gallery
I went as far to actually build and install the broken package:
$ sfdk config target=SailfishOS-4.5.0.18-aarch64
$ sfdk build
$ sfdk config device="Xperia 10 II - Dual SIM (ARM 64bit)"
$ sfdk deploy --sdk jolla-gallery
Sure enough, the result was an app which didn’t show any images or videos on the device:
Start of the investigation
Now that I had successfully broken the app, it was time to try to fix it. Luckily, there exist a document which outlines the correct approach, so I didn’t have to spend too much time figuring out where to start:
Debugging sailjail application sandboxing. The document is actually written in such a way that it provides the instructions in pretty much the order in which you are supposed to follow them.
So, I start from step 1.1 Determining how to launch application:
$ sfdk device exec
[defaultuser@Xperia10II-DualSIM ~]$ rpm -qf /usr/bin/jolla-gallery
jolla-gallery-1.1.6+master.20230417094155.adc59fd-1.aarch64
Not surprising, the binary comes from the package which I had just installed. I could have probably figured that out even without running the rpm command.
[defaultuser@Xperia10II-DualSIM ~]$ rpm -ql jolla-gallery|grep desktop
/usr/share/applications/jolla-gallery.desktop
[defaultuser@Xperia10II-DualSIM ~]$ grep Exec /usr/share/applications/jolla-gallery.desktop
Exec=/usr/bin/sailjail -p jolla-gallery.desktop /usr/bin/jolla-gallery
There’s the exec line that’s used for starting the application. That’s enough information for me to move to the next step: 1.2 Execute the application
[defaultuser@Xperia10II-DualSIM ~]$ /usr/bin/sailjail --trace -p jolla-gallery.desktop /usr/bin/jolla-gallery
.../daemon/sailjailclient.c:499: client_set_trace_dir(): W: -p: is not already existing writable directory
Well that wasn’t expected. Turns out the instructions were a bit outdated - these days --trace
requires an argument. It took me a few minutes to figure this out. But don’t worry, the instructions are already updated, if you choose to follow them now, you shouldn’t bump into this issue.
So, in the end I managed to execute the application:
[defaultuser@Xperia10II-DualSIM ~]$ mkdir jolla-gallery-trace
[defaultuser@Xperia10II-DualSIM ~]$ /usr/bin/sailjail --trace=jolla-gallery-trace --profile=jolla-gallery.desktop /usr/bin/jolla-gallery
Privileged application
The application starts, but thera are a lot of error messages on the console. One line jumps out almost immediately:
** (process:26): WARNING **: 13:46:12.458: Cannot create directory: /home/defaultuser/.local/share/system/privileged/Accounts/libaccounts-glib
Privileged? Wasn’t there something about privileged apps in the document?
Right, there’s an entire chapter about Tracing privileged applications. So, jump to step 2.1 Determining application launch files.
The desktop file we already know, but now the instructions talk also about a service file.
[defaultuser@Xperia10II-DualSIM ~]$ rpm -ql jolla-gallery|grep service
/usr/share/dbus-1/services/com.jolla.gallery.service
Following the instructions in chapter 2.2 Enable sailjail/firejail tracing I add the trace parameters to the desktop and service files:
[defaultuser@Xperia10II-DualSIM ~]$ mkdir /tmp/gallerytrace
[defaultuser@Xperia10II-DualSIM ~]$ sudo nano -w /usr/share/applications/jolla-gallery.desktop
...
[defaultuser@Xperia10II-DualSIM ~]$ sudo nano -w /usr/share/dbus-1/services/com.jolla.gallery.service
...
I added the --trace=/tmp/gallerytrace
parameter to the Exec lines of both files. In the process I noticed that it’s important to have the same parameters on both files, otherwise the application won’t start at all.
The trace files
After editing the files it was time to start the app from the app grid. Not surprisingly, it hadn’t magically fixed itself, and the app still doesn’t show any pictures. But now, after exiting the app, I had trace files in /tmp/gallerytrace
. I started going through them, as instructed in chapter 3 Interpreting the trace files, starting with firejail-stderr.log
.
In the log I notice familiar error message:
** (process:26): WARNING **: 09:07:25.806: Cannot create directory: /home/defaultuser/.local/share/system/privileged/Accounts/libaccounts-glib
Now, I look at the list of existing permissions and see a permission called “Accounts”. It sounds promising, so I modify the jolla-gallery.desktop
file to have:
Permissions=Accounts
and start the app again.
Or to be more precise, I try to start the app. It doesn’t start. Running ps axf | grep gallery
shows many gallery processes running, I just kill them all and try again. Now the app starts and I have some fresh trace log files to investigate.
Surprisingly, it looks like things have gotten worse instead of improving: There are more errors in firejail-stderr.log
than before!
Error: can't chdir to privileged
Is there some permission required for accessing privileged data? The permission list doesn’t have any. So I decide to look at the sailjail sources:
sailjail$ grep -r -i privileged *
...
I notice there is an interesting comment in daemon/permissions.c
:
/* 'Privileged' exists even if there is no
* matching permission file present.
*/
So, I add Privileged
to the permission list in jolla-gallery.desktop, kill all gallery processes, and try again. And now there is actually some visible change in UI: A dropbox folder appeared! No images though. I open a PR for including the Privileged permission in the documentation and move on.
Now firejail-stderr.log
contains no more error messages. It’s time to look at the next file, firejail-trace.log. Just like mentioned in the instructions, there are lot’s of errors, as the system tries to find the libraries and other files in various locations. These are harmless, as the files are eventually found, or the files don’t really exist on the device, which is not related to sandboxing. The first “real” error I find is this:
27:jolla-gallery:__xstat64 0 /home/defaultuser/android_storage/ 0x7fef7feda0:-1 (errno=2)
/home/defaultuser/android_storage exists
, and I remember that jolla-gallery should show files also from there. I decide to have a look at the permissions repository if I could find some hints there:
sailjail-permissions$ grep -r android_storage *
permissions/Documents.permission:whitelist ${HOME}/android_storage/Documents
permissions/Music.permission:whitelist ${HOME}/android_storage/Music
permissions/Music.permission:whitelist ${HOME}/android_storage/Podcasts
permissions/Downloads.permission:whitelist ${HOME}/android_storage/Download
permissions/Pictures.permission:whitelist ${HOME}/android_storage/Pictures
permissions/Pictures.permission:whitelist ${HOME}/android_storage/DCIM
permissions/Videos.permission:whitelist ${HOME}/android_storage/Movies
Well, the gallery app should be able to show pictures and videos. Let’s add those permissions.
Well, we have more folders now. But those are still empty, except for the Nextcloud folder.
Investigating DBus logs
As the trace log doesn’t provide more hints, it’s time to move to the next part of the instructions - firejail-dbus.log. The instructions say that I should look for SKIPPED or HIDDEN entries. There are quite a lot of SKIPPED entries, like:
C2: -> org.freedesktop.DBus fake AddMatch for org.freedesktop.Notifications
B3: <- org.freedesktop.DBus return from C2
*SKIPPED*
That does not really seems relevant, so I decide to ignore these now, and focus on the HIDDEN entries.
C146: -> org.freedesktop.Tracker3.Miner.Files call org.freedesktop.DBus.Peer.Ping at /org/freedesktop/Tracker3/Endpoint
*HIDDEN* (ping)
Now this looks interesting. Tracker is a search engine which Sailfish OS uses for indexing media files - and the gallery uses it for finding the pictures and videos. The permission list says that MediaIndexing
is needed for accessing Tracker. So, let’s add MediaIndexing.
Success!
Fixing the app
Well, not quite there yet. Trying to watch videos, I notice that the videos don’t have sound.
Looking at firejail-trace.log I find a new message:
29:jolla-gallery:fopen64 /etc/pulse/client.conf re:(nil) (errno=2)
The device definitely has that file - so we need to find a permission which gives access to it.
sailjail-permissions$ grep -r pulse *
permissions/Base.permission:# Disables access to pulseaudio by default
permissions/Audio.permission:private-etc pulse
permissions/Audio.permission:whitelist ${RUNUSER}/pulse
permissions/Audio.permission:read-only ${RUNUSER}/pulse
permissions/Audio.permission:mkdir ${HOME}/.config/pulse
permissions/Audio.permission:whitelist ${HOME}/.config/pulse
permissions/Audio.permission:whitelist ${HOME}/.pulse-cookie
permissions/Microphone.permission:# TODO: playback and record streams cannot be separated on pulseaudio, remove this when they are.
There’s the line private-etc pulse
in Audio permission. That should give access to /etc/pulse, so let’s add that - and now we have working audio in videos!
So now my permissions look like this:
Permissions=Accounts;Privileged;Pictures;Videos;MediaIndexing;Audio
My test cases passed, I decide to end the investigation here. As a final step, I compare my end result to the actual released version of jolla-gallery. The released version has a bit more permissions than what I ended up with: Instead of just Pictures and Videos, the released version has UserDirs
- fair enough, I guess it’s useful to be able to look at files outside of Pictures and Videos folders. There’s the Ambience
permission - jolla-gallery allows you to create an ambience from a picture, so that is clearly needed. Internet
- that is probably needed for streaming from network, I have heard that some people do that. RemovableMedia
- ok, it’s not uncommon to have pictures on a SD card.
But Synchronization
and Accounts
? It was later brought to my attention that these are needed by the dropbox integration, which I didn’t test. And it actually needs Internet
as well. Thinking further, it’s quite likely also nextcloud would have needed those, I was just lucky to have all my nextcloud photos in the cache.
App roundup
There’s a bit of a science theme to the apps this fortnight, ranging from the latest Artificial Intelligence sensation to a neat gaming twist that manages to make maths fun. It’s great to see the continual investment of developer time into the platform, bringing new ideas with potential for exciting and new developments in the future. Whether you prefer your science to be a tool that makes your life easier, or a source of challenge that makes your life harder, you’re sure to find something of interest in these picks.
ChatGPT
While the world has been going a bit crazy about Artificial Intelligence, it might seem reasonable to ask what all this commotion will mean for our beloved Sailfish OS. Until now, Sailfish OS has largely steered clear: no ambiguous or unreliable voice assistant, no constant data collection or behavioural analysis to help surface commonly used or hidden functionality. Just a clear, consistent, interface that leaves the user in control.
But while there are still many questions concerning the efficacy and ethics of large language models to replace search, recent advances do make it feel like Artificial Intelligence on mobile is finally turning the corner from inconsistent curiosity to useful tool.
With all this in mind, it was therefore exciting to see a ChatGPT app appear in the Jolla Store. Created by Dominik Chrástecký (Rikudou_Sennin), this is an unofficial client that will allow you to have text-only conversations with the ChatGPT chat bot. The experience is similar to chatting with it via the chatgpt.org website, but using a slick and more consistent Sailfish user interface.
In many ways it feels similar to using the Sailfish Messages app, with your queries appearing in right-aligned bubbles, and ChatGPT’s answers appearing left aligned underneath them in a scrollable list.
In the background the app is making use of the ChatGPT API, so you’ll need a working internet connection, as well as to provide a ChatGPT API key, to get it to work. In order to get an API key you’ll need to create an OpenAI account, as well as submit to your data being collected. But the process of setting up the app is otherwise pretty painless.
In use, the app is generally pretty slick. Responses are returned quickly and printed out progressively (a word at a time) in the way users of the ChatGPT website will be familiar with. There are a few glitches that make it slightly harder to use, such as when the text entry box overlaps the responses, and it has a tendency to scroll to the first question in a conversation each time, but these are minor issues that no doubt Dominik will be able to fix in future updates.
Speaking of updates, the app has already been through several revisions and is now on version 0.9.6. There’s no integration with the operating system, so don’t expect it to be a replacement for a virtual assistant, but it does provide a very straightforward and gentle introduction to AI chat.
Dominik’s ChatGPT app is available from the Jolla Store, and OpenRepos. As has become customary in anything AI-chatbot-related, I’ll leave the last word to ChatGPT itself. How does it see the Sailfish OS ChatGPT app?
Overall, the Sailfish OS ChatGPT app is an excellent example of how machine learning models, such as GPT, can be integrated into a chat application to create a conversational AI interface that’s both user-friendly and informative.
Babbage
On Sailfish OS we’re blessed by a plethora of different calculator apps, many of which have featured in previous newsletters. If you’re someone — like me — who’s first experience of computing was via an LCD pocket calculator, using fleshy digits to enter digital digits and ambiguous operator precedence come naturally. But younger generations who’ve grown up surrounded by computers and programming, I’d expect to be more likely to crack open a Python shell to add numbers together.
Babbage from Heiko Bauke (bauke) fits into a middle ground, somewhere between the flexibility and complexity of a Python shell, and the simplicity and immediacy of a pocket calculator. Does it hit the right balance though?
The first thing to note is that it doesn’t do away with the digit-jabbing pocket calculator interface entirely. Like the standard Sailfish OS calculator app, it offers a two-tier interface: simple and complex; depending on your preference.
When set in “Pocket calculator” mode it provides a Sailfishy interface that nevertheless feels a bit more traditional than the standard app. You can enter expressions of any length, but only using the 23 buttons available on screen. These include brackets, square root, exponentiation and pi, but nothing more complex than that. There’s no history scroll, but you can store a single value in a register for future recall.
The magic really happens when you switch to Scientific calculator mode. Now the input area turns into a standard text entry field, the onscreen buttons replaced with the standard Sailfish OS keyboard. Here you can enter expressions, including using variables with assignment and manipulation. The history rolls down below the entry field after each expression has been evaluated, plus you can use 42 additional multi-variable functions that range from trigonometry to statistical testing functions. A separate page allows you to inspect your variables, and there’s even some simple typesetting rules that make the functions you enter much more readable.
It’s a very nice calculator app, and a decent intermediary point between a basic calculator and a Python shell. There are some small areas that offer room for improvement: it would be great if — like the variable storage — the history persisted across restarts. It’s a shame the list of functions is hidden in the About page. And for the life of me I couldn’t figure out an easy way to enter the new arc degree symbol.
Variable storage is a new feature for version 0.19, alongside the arc degrees, radians and Sailjail support. It’s an accomplished and useful mathematical tool.
Babbage is available from the Jolla Store.
VibrationTest
At a recent Sailfish Community Meeting the topic of vibration strength was raised. Different devices have different vibration motors and so can provide a different haptic experience with the same settings. The suggestion at the meeting was to allow the values to be more easily configured.
VibrationTest from zuyev doesn’t solve this problem, but it does allow you to play around with different strengths and durations of vibration to understand how they feel.
This can be useful for developers — who have some control over the haptic feedback of their apps — but may also provide curiosity value for other users too. With a bit of effort, you can technically change the haptic configuration of your device (although this isn’t recommended, and any such changes are done at your own risk!).
VibrationTest allows you to check the default values for Buttons, Long presses and so on. In addition you can configure the duration and intensity of the vibration. as well as a repeat delay, to see how this feels in practice. A separate page even allows you to configure a synthesizer-style envelope: attack, fade and period settings.
It’s important to bear in mind that having found the perfect combination the app doesn’t allow you to set these as the actual values used throughout the user interface. The app is only meant to be used for testing. And while I wouldn’t personally use this app outside of app development, it nevertheless is of interest value.
The VibrationTest app is available from both the Jolla Store and OpenRepos.
Calcit
With our last app we’re moving into gaming, but nevertheless not moving entirely away from sciencey stuff. Calcit from Mark Washeim (poetaster) is an interesting numerical riff on the Wordly formula, replacing letters for numbers and operators (plus, minus, times and divide).
Wordly is super-popular and at this point needs no introduction. But efforts to create a successor with similar levels of enjoyment and popularity have been largely unsuccessful. So does Calcit break this trend and manage to improve upon the winning Wordly formula?
Well, I’ll leave it to you (and history) to decide. But there’s no doubt that Calcit is an enjoyable game. It lacks the simplicity of Wordly, but it does get one thing right: while Wordly exercises the player’s vocabulary, Calcit stretches the player’s mental arithmetic. In that sense, it reminded me of the Countdown Numbers Round: working through the possible combinations of mathematical expressions forces you to get to grips with performing factorisation in your head.
You’re given six guesses, each of which is an expression of four single-digit numbers separated by three operators (number, operator, number, operator…). These must be evaluated to output the fixed result shown on the right of the equality.
There’s no help built into the app itself. Given this it’s worth noting that expression are evaluated with multiplication and division having higher operator precedence than addition and subtraction. That’s standard mathematical practice, but the Wordly context made me naturally expected it to be left-to-right precedence. Practically speaking this makes things a little harder in my view, but is also the correct approach.
The app itself uses a WebView to wrap a JavaScript implementation of the game. The presentation is bright (the throbbing celebratory exclamation when you win is a nice touch) although lacks the usual Sailfish styling. Double tapping a key (“delete, delete,…”) will also trigger the browser to zoom in rather than react to the intended button press. But these are minor gripes for a first release, and with any luck (and going by his other releases) Mark will continue to improve on the app over time.
Calcit is an enjoyable addition to the growing selection of Sailfish games, a great way to have fun while at the same time improving your mental arithmetic skills. It’s also yet another app to add to Mark’s growing compendium of apps, a really valuable contribution to the Sailfish OS ecosystem.
It’s available from the Jolla Store, OpenRepos and Chum.
Repository roundup
The network stack
-
connman
, the connection manager, LaakkonenJussi fixed problem on device start-up when the communication devices are not yet set-up while the system tries to apply regulatory domain from the timezone reading. LaakkonenJussi is also proposing to reverse the commit adding longer timeout to establish connection. It seems that it’s not solving the problem.
The telephony stack
-
ofono
, the telephony library, mal got his work on 5G support merged in. -
liqofonoext
, a library for accessing Sailfish OS specific ofono extensions, mal added support for 5G properties.
Calendar stack
-
mkcal
, storage backend using SQLite for calendar entries, dcaliste fixed an issue affecting recurring alarms (see Calendar alarms don't work for recurring events since SFOS 4.5.x.x [Solved]). dcaliste is also proposing a pull request to include recurring events in search results so they can appear with their next occurrence, even if they started a long time ago (like birthdays). -
contactsd
, the daemon handling contacts, dcaliste submitted a pull request not to clear birthday alarms when a birth date is changed. -
nemo-qml-plugin-calendar
, the QML bindings for calendar events, dcaliste pushed a request to be able to save modifications to notebooks with the read-only hint, like birthday ones.
Low level libraries
-
sdl
, a multimedia library, mlehtima continues to work in a branch on upgrading to the latest upstream version 2.26.5. -
libglibutil
, a library extending GLib with convenient utilities, slava pushed various commit, including runtime version checks or tools to handle TLV data encoding (see this Wikipedia page on Type-Length-Values). -
libmce-glib
, Glib client for mce, spiiroin added support forMceInactivity
which expose device inactivity. The pull request also contains a commit adding a example program on how to use the Glib bindings to Mce. -
sensorfw
, sensor framework, spiiroin added proper initialisation avoiding warnings at construction time. spiiroin also fixed a missed conversion since internally sensorfw is now using micro-seconds but still report milli-seconds over DBus.
SDK and developer tools
-
sdk-harbour-rpmvalidator
, the harbour validation scripts, vigejolla added a warning when theX-Sailjail
section is missing from the desktop file. -
less
, which is more powerful thanmore
, mal packaged it and added it in the distribution. -
amber-web-authorization
, a QML module allowing applications to perform OAuth1 and OAuth2 requests, vigejolla migrated its documentation to use Sailfish template instead of Mer one. -
sdk-user-manual
, examples and documentation for the SDK, vigejolla also migrated the documentation of this package. -
sailjail-permissions
, the configuration files for system-wide sandbox permissions, vigejolla added a sentence explaining thePrivileged
permission. -
sailjail
, a wrapper around firejail, vigejolla clarified documentation for the--trace
argument.
Please feed us your news
Thanks for reading this far! As always, we are waiting for your feedback and ideas.