Sailfish Community News, 17th June, Sailjail

Subscribe to future posts here :bell:

Sailfish OS update from Jolla

Let’s start with an important reminder. Usually this newsletter would be released just before the Community Meeting, but the meeting has been shifted by a week. The next meeting will therefore be taking place on the 24th June at 7:00am UTC. It’s always great for us at Jolla to be able to interact directly with members of the community, so please do join us if you can.

On Monday the promised migration of our project code from gitlab to github was completed. This makes things tidier and easier by concentrating all our code in one place, while also making the contribution process easier given that most developers will already have a github account. The previous gitlab repositories will remain accessible in a read-only state for the timebeing, but the code in them won’t be updated, so please direct your browser to github.com/sailfishos for all of the Sailfish OS code in future.

Last week saw an important SDK release, with Sailfish SDK 3.5 moving out of Early Access and into General Release. That means that if you’re an SDK user you should by now have already been offered the upgrade when starting up the IDE. This new release includes a bunch of changes and new features, including an update to Qt Creator 4.14.2, support for signing RPM packages, a host of improvements to the command-line sfdk tool, and a myriad bug fixes. Great work from the SDK team and all the contributors.

Inside Jolla, the release cycle is very much a continuous process rather than an event. Nevertheless there are certain milestones that mark the journey. We hit one of them this week with the start of the latest localisation round for the 4.2.0 release. We’ve talked in previous newsletters about the amazing work the Sailfish OS language coordinators and translators do, but it bears repeating and our admiration for their work doesn’t diminish just because we’re not talking about it. If you’re part of this process, you’ll already be well aware of the impending translation deadline of 20th June. Even if you’re not a translator it can be worth keeping an eye on what’s happening with Sailfish localisation, since it’ll often provide an insight into the upcoming release.

Earlier in the year the 4.0.1 Koli release of Sailfish OS introduced Sailjail sandboxing to the operating system, something that we discussed a bit in the blog post for that release. Primarily due to it being a new and experimental feature, the sandboxing at that time was only applied to the official Jolla apps. This situation continued with the 4.1.0 Kvarken release a few weeks ago. Nevertheless we’ve been working in the background to build on this with the intention of rolling it out to a broader set of apps in future releases.

This will be an important change for many reasons. Not just because of the benefits it will bring to end-users in terms of security and privacy, but also because of how it might affect third-party app development.

The exact changes that app developers will need to apply in order to support the sandboxing features aren’t yet set in stone, and so remain fully subject to change. Nevertheless we thought it might be good to spend a bit of time discussing them here, just to give a flavour of what’s ahead. Don’t worry if all of the technical details aren’t fully transparent yet, there will be much more guidance made available about this as things progress.

Sailjail: what is it, where did it come from and where is it going?

Even though Sailjail sandboxing for the Jolla apps was a new feature introduced in 4.0.1, it’s been gestating inside Jolla for quite some time. I spoke to two of Jolla’s experienced Software Engineers who’ve been working directly on the design and code. With their help I’m hoping we’ll be able to get a better understanding of what Sailjail is all about. Andrew Branson has been a Middleware Engineer at Jolla since 2016 and is based in Thoiry, just on the French side of the Swiss-French border. As well as the sandboxing he’s also worked on the browser multimedia and Android App Support. Tomi Leppänen is a Software Engineer at Jolla who started out using a Nokia N9 back in the day and says “it was quite natural to move from there to a Jolla phone with a better supported platform”. It’s something I’m sure many of us can relate to. That choice eventually led to him joining Jolla in 2018, based at Jolla’s HQ in Tampere, Finland.

Andrew was one of the early developers working on the sandboxing project, as he explains:

Investigations have been ongoing for a couple of years, assessing different sandboxing tools and methods and producing proof-of-concept implementations. We settled on Firejail and started work on Sailjail last summer.

So sandboxing of apps has been part of the internal roadmap for a while, and you can see some of the earlier references in the blog post for 3.3.0 Rokua, and Raine Mäkeläinen’s discussion on shared mobile devices last year. But what actually is sandboxing? Andrew goes on to explain:

Sandboxing provides apps with a safe ‘sandbox to play in’. Apps run in a restricted slice of the system so they can do only what they’re supposed to do and can’t cause damage, even if they’re:

  • Malicious: an app can’t access sensitive parts of the system without your permission.
  • Hacked: an app with a security vulnerability could be hacked, but any malicious code that’s added to it can’t do anything that the original app wasn’t allowed to do.
  • Buggy: apps may have bugs, and those bugs could cause unintentional damage by for example overwriting other data. Sandboxing limits what apps can see and what they can overwrite, so an app can by default only ruin its own data.

In Sailfish OS, app sandboxes are built using containers, and have the following features:

  • Apps run in their own Linux Namespaces, so they can’t see other apps running nor their network connections.
  • They run in a virtual filesystem which only contains directories and files that the app needs to run. Other data and code belonging to other apps isn’t visible to them.
  • Software services are proxied, so apps can’t talk to any system components that they don’t need.

There have been several iterations of the sandboxing capability that looked at different technologies for isolating apps in different ways. As Andrew explains above, the implementation that was settled on, and which was deployed in 4.0.1 Koli is based on the Firejail security sandbox. As described on the Firejail website, it “allows a process and all its descendants to have their own private view of the globally shared kernel resources, such as the network stack, process table, mount table.”. Tomi explains this in a little more detail:

The sandboxing is based on Firejail which sets up the sandbox itself. Firejail provides sets of rules called profiles for common desktop apps, but in Sailjail we break profiles down into ‘permissions’: fragments that group together rules that grant certain interactions with the system. For example, the Photos permission will include access to the user’s Photo directory, but also to Tracker so the index of those photos may be used.

Firejail is an upstream component we use and contribute to which uses Linux’s namespacing features to set up a “jail” with a limited view on the file system, users and sockets. It also sets up xdg-dbus-proxy which acts as an intermediary between the system D-Bus or session D-Bus, and the application so that we can control which services and interfaces are available.

On top of that we have built Sailjail which is the glue that manages permissions for apps. It reads what an application wants, in terms of permissions, from the app’s .desktop file, asks the user if they’re willing to accept these permissions and instructs Firejail to use the correct rules.

Then there is mapplauncherd that starts (and pre-loads applications to speed up those launches) applications. We had to adapt this for sandboxing although it doesn’t directly take part in the sandboxing of apps.

If you’re interested to take a look at the technologies being used, the best places to start are in the sailjail and sailjail-permissions repositories on github. You’ll notice there’s been a lot of activity there recently. And you might also want to take a look at the upstream Firejail project. As Andrew says “Firejail is a third-party sandboxing tool, that is open source and geared towards transparently sandboxing desktop apps. You can find the source code on github, and it’s available in most Linux distribution repositories.”

This all sounds well and good, but what does it actually mean for end-users in practice? Here’s Andrew again.

When you launch a sandboxed app for the first time, a system prompt will appear to ask you if you want to allow the app to launch with the permissions it has requested. At the moment it isn’t possible to pick and choose from this list, but this could be possible in the future. In the Settings app, you can see which permission each app has been granted in the Apps tab.

Aside from the increased security sandboxing provides, making sure that Sailfish OS apps can’t do anything sneaky that you haven’t allowed, the new permissions system means that it might be possible to allow apps to request access to data that wasn’t previously allowed by Jolla store rules. For example, apps may potentially be able to access your address books and calendars, if you choose to let them.

So this is still just something that’s being explored, but it’s interesting to think that restricting apps in a way that provides more transparency and control for the end user, should allow us to offer more access to certain functionalities than is possible at the moment, as long as the harbour requirements are met. That’s one of the benefit of a granular, as opposed to an all-or-nothing, approach.

Hopefully this gives a better understanding of the technologies and intentions behind Sailjail. But if you’re an app developer and you’ve read up to here, you’ll no doubt be wondering what this means for you. Are you going to have to re-write your app to make use of all the new sandboxing features?

To answer that we have to get a bit speculative, because these details aren’t all fully decided. However, we can give you an idea about how it works at the moment in 4.1.0 for the official Jolla apps, which is more than likely going to bear some resemblance to how it will roll out for other apps eventually. Recent changes that we’ve discussed elsewhere have meant that app developers have already had to do some work to create aarch64 versions of their apps. We’ve been impressed with how rapidly and effectively our community of developers has pulled together to achieve this. Nevertheless, the intention is to keep disruption caused by sandboxing to a minimum. As Andrew puts it:

Sailjail has been designed to change the application running environment as little as possible, hiding things rather than moving them around.

But, it will inevitably require some effort on the part of app developers. Please note that some of the required changes are not yet allowed by the current Harbour rules, so you might want to wait a bit before making the actual changes.

Sailfish OS will be enforcing standard user data paths for apps in the future, mounting only those for your app, ~/.local/share/*subdirectory*/. The same applies to ~/.config and ~/.cache.

Through permissions, sandbox-aware apps may be able to request access to user data that hasn’t been allowed in Sailfish OS until now.

We’ve also looked at allowing your apps to provide their own permission files, allowing other apps to request access to your app’s services and data (non-private, in other words directories your app creates in the user home, not including app data in .local and so on).

If you want to take a look at the permission files for the official apps you can find them in /etc/sailjail/permissions/, each a file with a .permission extension. Over to Tomi:

We actually have three types of files in play here:

  1. .permission files that describe the types of permissions that an application is able to request. These are the permissions that are visible for the user, listed when an app starts for the first time;
  2. .profile files that are just a workaround for situations where permissions don’t allow enough flexibility for a specific app;
  3. .desktop files that are also known as application profiles where an app developer defines the set of permissions that their application needs to fully function.

As an app developer you’ll already be familiar with the .desktop files, since you’ll have needed to create one for each of the apps you’ve developed. They end up stored in the /usr/share/applications/ directory. Here’s the Sailjail section of the .desktop file for the official Gallery application as an example:

[X-Sailjail]
Permissions=Pictures;Videos;MediaIndexing;Downloads;Sharing;Ambience;Internet;Synchronization
OrganizationName=com.jolla
ApplicationName=gallery

Let’s break this down a bit. The [X-Sailjail] header indicates that the key-value pairs which follow are all related to the Sailjail sandboxing. We then have the Permissions list. Each of these is a reference to one of the .permissions files found in /etc/sailjail/permissions/. Each of them also represents a “headline” permission which will be presented to the end user. We can see this when we fire up the Gallery app for the first time and are presented with the following dialog. Selecting one of the entries provides a brief summary of the permission.


They’re not all listed in the same order, but apart from that you can see that the permissions presented to the user are the same as those listed in the .desktop file. The remaining two items OrganizationName and ApplicationName are used for defining the standard user data paths highlighted by Andrew above. Some current apps will already be setting these values in their C++ code, something like this:

QCoreApplication::setOrganizationName("org.foobar");
QCoreApplication::setApplicationName("bar");

The values set like this will have to match the values given in the .desktop file in order for the sandbox to know that it must provide access to the same data paths that Qt uses based on the C++ code.

As you can see, making these changes shouldn’t be hard, but if it’s not done properly it will likely cause problems for apps and confusion for users when their settings are reset each time the app is closed. Having said that, for apps that don’t explicitly specify permissions, we’re also hoping to minimise any adverse consequences, as Tomi explains.

We have also been working on sandboxing all apps by default which means that if the configuration says so, every app is sandboxed with a default set of permissions (unless the app explicitly opts out). Take a look at pull request 83 in the sailjail-permissions repository to see how this is developing. This builds on a set of assumptions about the application, see the changes to the README.md file for more info.

Returning to the explicit permissions, their names (Pictures, Videos, MediaIndexing,…) sound rather clean and simple, but they actually break down to a lot of very fine-grained and complex configurations. We can take a look at what’s needed for the “Ambience” permission by looking inside the /etc/sailjail/permissions/Ambience.permission file:

# -*- mode: sh -*-
# x-sailjail-translation-catalog = sailjail-permissions
# x-sailjail-translation-key-description = permission-la-ambience
# x-sailjail-description = Ambience
# x-sailjail-translation-key-long-description = permission-la-ambience_description
# x-sailjail-long-description = Create, modify and delete ambiences

mkdir ${HOME}/.local/share/ambienced/wallpapers
whitelist ${HOME}/.local/share/ambienced/wallpapers

dbus-user.talk com.jolla.ambienced
dbus-user.broadcast com.jolla.ambienced=com.jolla.ambienced.*@/*

mkdir ${PRIVILEGED}/Ambienced
privileged-data Ambienced

These lines essentially tell Firejail how to set up the sandbox. Skipping past the lines starting with #, the first two commands (mkdir and whitelist) relate to the directories that the application has access to. The filesystem sandbox is like a bare-bones copy of the complete filing system that’s dedicated to that one application. If the app writes to a file, it writes to its own copy, and when the app is closed those changes are lost. The first two lines tell Firejail that the ~/.local/share/ambienced/wallpapers directory must exist in the sandbox, and that rather than being a copy, it should instead link to the real contents of the directory on the operating system filesystem. So if the app changes something in that folder, it will be a change to the original copy, and will persist even after the app has closed.

Then we have two dbus related commands. These tell the sandbox to grant the app the ability to access services provided through the com.jolla.ambienced interface. They state that the app is allowed to call methods and listen for signals on this interface. Without these lines the app would be blocked from doing either.

Then finally we have another couple of lines that give the app access to some privileged data related to ambiances on the device.

This is just a flavour of what’s going on and there’s plenty more detail to get into. If you want to know more, then some good places to start are the Sailjail README.md file and the Firejail man pages.

By this point we’ve gone into quite some detail already, but hopefully it’s clear that as an app developer, the main changes will involve figuring out what permissions your app needs, ensuring your app stores any data to the standard paths, and then editing your .desktop file to match.

We already mentioned the constituent pieces of Sailjail and the fact you can find the code for them on github. We’re always really keen to have input from community developers and the fact that this is possible is one of Sailfish’s biggest strengths. So if you’re interested in getting more involved with sandboxing development, what can you do? Let’s finish off with Tomi offering suggestions.

For community members who are interested to help, trying it out and discussing any issues is helpful to us for understanding the requirements. However, note that at the moment this is not Harbour-approved stuff. Coming up with useful rulesets (permissions) could be beneficial, if there are some corners we have clearly missed. Of course we are also ourselves working on improving those. However it’s not always possible to create useful permissions without changing the implementation beneath. For example some accesses are file-based and very lax in terms of exposed data but usually we need quite specific permissions. Often this can be solved by daemonizing the access first.

It goes without saying, but I’d like to say a big “thank you” to the whole Sailjail team, and Andrew and Tomi especially, for the massive help they provided in writing this. If you’d like to talk to either of them directly, they’re long-time regulars at the Sailfish Community Meetings, so do join us there.

Energy from the Community

The updated apps for aarch64 continue to roll in, and a huge thank you to all of you who have made the effort to upgrade your packages. It’s great to have such a wide selection to choose from, but as always we’ve had to pick just a few new and updated apps to highlight here.

Reisplanner

Last time we had a look at a couple of public transport apps of use for getting around the UK. This time we have an update for Reisplanner by rgrnetalk, offering something similar, but in this case for travelling around the Netherlands. Reisplanner uses data taken from NS, the Dutch national rail operator, so in practice its reach extends beyond the national borders of the Netherlands. You can also use ReisplannerBE from the same author and with similar features, but which makes use of the irail.be API instead. To use the app just give it a starting station and a final destination station and it will plan a route by train between them. You can also set intermediate waypoints that the route will then pass through. Having found an appropriate route you can drill down to find not just the start and end station for each leg of the journey but also all the intermediate stops. A particularly nice feature is the ability to skip to the next earlier or next later departures for the same route just by selecting the item from the menu. It’s such an obviously useful feature, but one that I’ve not seen implemented so neatly on other apps or websites. As well as train routes you can also pick up live information about disruptions on a route. Sadly I wasn’t able to make it all the way to the Netherlands to test this out. What I can say is that the app was very responsive and the info it gave was comprehensive. The latest version improves visibility for the route details, adds the nice “earlier” and “later” journey options, adds various other pieces of useful info to the output and fixes several bugs. Well worth installing if you’re travelling in the areas it covers. Reisplanner is available from the Jolla Store.

Fotokopierer

I used to own a desktop computer, a monitor, a printer, a scanner and a yacht. Now I achieve the same functionality just with my smartphone. Fotokopierer by fifr fulfils the role of one of these devices (no, not the yacht I’m afraid) by allowing you to dual-use your smartphone camera as a scanner. It’s a simple enough concept, and at a pinch you could even get away with just using the default camera app to do the same, but Fotokopierer has some neat tricks to make the process that much easier and more effective. First, it will neatly catalogue all of your ‘scanned’ files in its own index, to avoid them getting mixed in with all of your cat photos. Second, after you’ve taken the photo it allows you to adjust the colouration with some simple controls. Line drawings can be converted to black and white, there’s a greyscale option, or you can optimise for colour. You can also manually adjust the brightness and contrast to tweak the results in just the right way. Finally, and in my opinion the feature that justifies the app on its own, is the ability to automatically detect the document edges, and use this to transform and crop the image to form a nicely rectilinear capture just like the original. This means that even if you take the photo at an angle (which is a particular hazard while scanning images at sea) you can still get a result that pretty-well approximates a flat scan. In my trials I found the app did a pretty decent job of automatically figuring out the borders of the document I was attempting to capture, and even when it doesn’t quite figure it out correctly you can still manually adjust the boundary by dragging the onscreen handles to the corners or edges of the document. The only slight glitch I hit with the app was when processing took longer than expected. Because all processing is performed on the UI thread the app could occasionally become unresponsive. But let it do its thing and it will return to life after a short pause. All-in-all a really neat and useful app. The latest version supports aarch64 and also improves the beta PDF export. Sadly, it’s not entirely true that I owned a yacht, but it is true that Fotokopierer is available from the Jolla Store and OpenRepos.

Quanto Fa

To quote from the About page, Quanto Fa by Montanaro Luciano (mikelima) is an “RPN calculator based on the HP-35 simulator from the HP museum”. Classic scientific calculators are a bit of a big deal in some quarters, and I know how upsetting it can be for aficionados when people get the details wrong. So let me admit upfront that classic calculators aren’t something I know a great deal about. But I do appreciate the value of a good RPN implementation, and Quanto Fa certainly provides that. It can make entering complex calculations that would feel cumbersome on a standard calculator feel swift and natural by comparison. But using it effectively can require a bit of practice. In essence an RPN (Reverse Polish Notation) calculator uses a stack-based approach to processing, rather than attempting to mimic the left-to-right reading of mathematical notation a normal scientific calculator (or an interpretive console like Python) would use. You place the arguments on the stack, pushing onto the stack by pressing ENTER, and only then state the operator to apply to them. So while a normal calculator expects 2 + 3 to be given by hitting the keys in order “2, +, 3”; with an RPN calculator you would type “2, ENTER, 3, +”. Quite logical really. An important benefit of RPN is that it obviates the need to use brackets when entering a complex calculation. Quanto Fa is a light implementation, so you don’t get to see what’s already on the stack, or stored in the memory. On the other hand this is a simulation of the first ever scientific calculator, so complaining about that is to miss the point somewhat. Personally I found it to be quite usable, I might even choose this “2, ENTER, 7, SIN, x^y, ENTER, 2, ENTER, 7, COS, x^y, +” over the standard calculator. The latest version has some nice UI improvements with larger buttons, output on the cover display and a better indication that the ARC prefix is in use. It also now offers Italian translations. Quanto Fa is available from the Jolla Store and OpenRepos.

Lyrics

It can be the most annoying thing, not quite remembering the words to a song. The Lyrics app by Andrea Scarpino (ilpianista) solves this by querying the online ChartLyrics database to pull up the lyrics for any song you can find there. It has good coverage of classic and popular songs, presenting the results in a clear way without distractions. You can even see the first couple of verses on the app cover from the homescreen, which is a nice touch. Its neatest feature is the ability to extract the artist and song title from the MPRIS data broadcast by the Media app (or whichever audio player your prefer, as long as it offers up controls on the lock screen) and to automatically seek out the lyrics as the song changes. It makes it feel like the app is always one step ahead. The lyrics database itself is pretty extensive, but certainly doesn’t cover everything. In the settings page there’s an option to select a lyrics provider, and although ChartLyrics is the only option available right now, it does hint at the prospect of other providers being added in the future (LyricsMania and Genius are both apparently in the pipeline). However, one downside to the app is that it will happily produce the lyrics for a different song without warning if it can’t find the one you’re after. This isn’t made obvious inside the app and I found I had to flick out to the homescreen to check the name shown on the app cover to be certain. It’s a minor quibble for what is otherwise a very nice way to access song lyrics. Lyrics is available from the Jolla Store and OpenRepos.

Please feed us your news

This is a community update, and frankly we can’t always keep up with all the exciting stuff happening in the Sailfish community. Plus, the less of this we have to actually write ourselves the better. So please help us out by posting your Sailfish news updates to the forum as a reply to this post. We’ll collate as much of it as possible into one easily digestable post for the next update.

And don’t forget to join us at the community meeting every other Thursday on IRC. It’s a great place to discuss any of the content you see here, or to share your ideas for future updates. The next meeting will be on the 24th June, full details here.

26 Likes

How is this done with Python or QML-only apps?

from PySide2.QtCore import QCoreApplication
QCoreApplication.setOrganizationName("org.foobar")

should work

Is there any way to make this work with PyOtherSide?

Pyside isn’t available for SFOS, is it?

Ah, Sorry. I’m actually using an experimental build of Silica and their vanilla pyside2 on a Raspberry Pi. I should shut up now :rofl:

(It’s an experimental hack; and No, I’m not allowed to share it, I asked :frowning: I just didn’t realise that pyside2 wasn’t what we used on the device. I’ll ask about that.)

5 Likes

Will there be a way to ask for permissions at runtime? For example, my app may want to allow you to send images from the gallery, but most of the time that access isn’t needed and may scare users.

Also thanks for the in depth post, very interesting!

3 Likes

In qml you just assign to Qt.application.organization and friends, see: Qt QML Type | Qt QML 5.15.4

1 Like

It still would be nice to have PySide2 non-GUI stuff available even without that hack. That would make porting PyQt/PySide stuff so much easier, as a rewrite of the data models on the Python side wouldn’t be necessary anymore.

Regarding Reisplanner, it appears the link to the source code in the Jolla Store is no longer functional, and I can’t seem to find ReisplannerBE on the Xperia 10 II. Is it supposed to be available for aarch64-based devices yet? @rgrnetalk

Thank you for mentioning my reisplanner app in the community news, that was a real surprise! @nthn I have removed it a long time ago, but never check whether it was removed from the store information, will ask QA to remove it. Haven’t found time yet for ReisplannerBE aarch64 build, but will upload it next week.

3 Likes

whatever you sailors decide;
please keep in mind that:
permissions are not the solution to all evil
android has made a mess with them; please do not go down the same path :frowning:

1 Like

Thank you so much for mentioning Lyrics! :heart:

I want to give it more love since I’ve been back, so please feel free to report any request for new providers, bugs and feature requests!

5 Likes