Tue, Apr 2nd, 2024

KDE6 release: D-Bus and Polkit Galore

Table of Contents

Introduction

The SUSE security team restricts the installation of system wide D-Bus services and Polkit policies in openSUSE distributions and derived SUSE products. Any package that ships these features needs to be reviewed by us first, before it can be added to production repositories.

In November, openSUSE KDE packagers approached us with a long list of KDE components for an upcoming KDE6 major release. The packages needed adjusted D-Bus and Polkit whitelistings due to renamed interfaces or other breaking changes. Looking into this many components at once was a unique experience that also led to new insights, which will be discussed in this article.

For readers that are new to D-Bus and/or Polkit, the following sections offer a summary to get a better idea about these systems.

D-Bus Overview

The D-Bus message bus system provides a defined way to implement remote procedure calls in applications. On Linux it is usually only used locally, although the D-Bus specification also allows for operation over the network.

A D-Bus service is a program that provides one or more interfaces that can be invoked by clients to obtain information, trigger operations and so on. The D-Bus specification defines a set of data types that can be passed to and returned from D-Bus method calls.

D-Bus applications reach each other by connecting to a shared bus of which there exist two predefined types: the system bus and the session bus. Services that perform system wide tasks connect to the system bus. These services often run as root or as dedicated service users. A session bus, on the other hand, is created for each (graphical) user session, and only applications running with the privileges of the logged-in user can connect to it. No special privileges are involved with the session bus. Its main purpose is to provide a defined API for session wide services, like a desktop search engine.

Polkit Overview

Polkit is an authorization framework that allows (privileged) applications to decide whether a user in the system is allowed to perform a specific action. These actions allow for a more fine-grained authorization model when compared to a plain root vs. non-root decision. Examples could be an action to enable a Bluetooth device in the system, or to mount a removable storage device.

A Polkit policy configuration file declares actions used by a certain application domain and the authentication requirements for it. When an actor in the system asks an application that uses Polkit to perform an action, then this application in turns asks the system-wide Polkit daemon whether this actor is privileged to do so. Depending on the context this can, for example, lead to a password prompt being displayed in a user’s graphical session to authorize the operation.

Polkit is independent of D-Bus, but the combination of both is a very common pattern. Other manners in which Polkit can be used is in setuid-root binaries or via the sudo-like pkexec utility.

Security Relevance of D-Bus and Polkit

The typical setup of D-Bus and Polkit is as follows: a system daemon is running with full root privileges and registers a service on the D-Bus system bus. An unprivileged user that is logged into a graphical session asks the daemon via D-Bus to perform an activity. This triggers the Polkit authentication process to determine whether the caller is allowed to do this.

Security-wise, there is quite a number of things that can go wrong in this scenario. The following sections investigate typical issues that can arise.

Covering all Privileged Code Paths

The system daemon actually needs to implement the Polkit authorization check properly for every sensitive D-Bus method it offers. Polkit is not something that is magically turned on, but the privileged component needs to identify all the code paths that need to be protected by it.

Some applications deliberately offer a mix of unauthenticated and authenticated D-Bus methods. In these cases it can sometimes be hard to keep all the possible side effects and outcomes in mind, which can lead to security issues when something is overlooked.

Acting as root on Behalf of Unprivileged Users

The privileged D-Bus service component often needs to act on behalf of an unprivileged client. An example could be mounting a file system in the caller’s home directory, or processing a file provided by the caller. This is a classic crossing of privilege boundaries. Developers of such services are often not aware of the problems that can arise, especially when accessing user controlled paths as root.

Similarly, if a privileged D-Bus service stores data from multiple users in a shared system directory, then information leaks can occur by storing files with too open permissions, or by mixing up different user contexts.

The Integration of Polkit can be Hard

Polkit has its own nomenclature and design principles that one needs to get into, to fully understand it. Apart from this, even if Polkit is correctly asked for permissions, the privileged service still needs to correctly evaluate the result. A typical mistake that can happen in this area is when a privileged service does ask Polkit correctly for authentication, but the result is simply ignored and the privileged operation continues regardless.

Everybody can Access the D-Bus System Bus

By default, all local users can access the D-Bus system bus and talk to most of the privileged services. Individual D-Bus service configuration files can limit the scope of users that are allowed to invoke a D-Bus service’s methods. This setup is the exception, however, as the majority of D-Bus services is accessible to all users.

This increases the attack surface notably, as not only an interactive user account that is running an authorized local session can talk to these services, but also e.g. the nobody user account. These days, many system daemons running on the network only have limited privileges or even use dynamically allocated users provided by systemd. If one of these network daemons with low privileges can be exploited, then weaknesses in privileged D-Bus system services can offer the possibility to further escalate privileges.

This is one of the reasons why, as part of a defense-in-depth strategy, the SUSE security team looks closely also into these components that aren’t directly attached to the network.

The KDE KAuth Framework

The KDE desktop environment is a heavy user of D-Bus services both on the system and on the session bus. It adds further abstractions on top of D-Bus and on top of Polkit. The base component for this is the KAuth framework. KAuth generates D-Bus configuration files and some glue code to integrate D-Bus and Polkit into KDE applications. In KAuth, a privileged D-Bus service running as root is called a KAuth helper.

We performed a dedicated follow-up review of it for the KDE6 release. A former member of the SUSE security team had found a major security flaw in this glue code in 2017. Since the audit at the time was comprehensive, we did not expect to find any major issues in the core authorization logic anymore, and in fact we didn’t.

Problematic use of QVariantMap Serialized Data

A peculiarity of KAuth is that, instead of the native D-Bus data types, only binary blob objects are transferred on D-Bus level, that are based on the QVariantMap data type offered by the Qt framework.

During the review we noticed that the implementation of this feature in KAuth is a bit shaky, since potentially attacker controlled data is processed during Qt data type deserialization, before the actual D-Bus function callbacks are even invoked. In 2019, the upstream authors had already identified this problem, that can lead to side effects like image data being deserialized, where actually only strings and integers are expected. The KAuth code currently meddles with internal Qt framework state to prevent such side effects.

Problems with generated D-Bus drop-in Configuration Snippets

Only late in our review efforts we realized that a change introduced with the KDE6 release of KAuth leads to overly open D-Bus configuration files being generated. Per-package configuration snippets for D-Bus are installed in “/usr/share/dbus-1/system.d”. These configuration files serve as a kind of firewall configuration for the D-Bus system bus. They define who is allowed to register a D-Bus service for a certain interface and also who is allowed to talk to it.

Here is a proper example taken from systemd-network’s “org.freedesktop.network1.conf”:

<busconfig>
        <policy user="systemd-network">
                <allow own="org.freedesktop.network1"/>
        </policy>

        <policy context="default">
                <allow send_destination="org.freedesktop.network1"/>
                <allow receive_sender="org.freedesktop.network1"/>
        </policy>
</busconfig>

This allows only the dedicated service user “systemd-network” to register the D-Bus interface “org.freedesktop.network1”, while any other users in the system may talk to it.

The KAuth KDE6 release candidate generated this configuration instead:

<policy context="default">
  <allow send_destination="*"/>
</policy>

The ramifications of this can easily be overlooked: this states that everybody is allowed to talk to everything on the D-Bus system bus. It also affects other D-Bus services that should not be influenced by the drop-in configuration snippet shipped for individual KDE packages. While most D-Bus services running on the system bus are “public”, i.e. everybody is allowed to talk to them, some services follow a different security model in which only dedicated users are allowed to interact with the service. We identified ratbagd as one such D-Bus service that would be negatively affected by this defect in KAuth. This shows that the security posture of unrelated packages is at stake. Luckily we identified this issue in time before the KDE6 release was finished, and the issue was fixed before it reached production systems. We also checked any non-KDE D-Bus configuration files we ship on openSUSE Tumbleweed for the same issue, but luckily found no further files containing this issue.

These side effects are also in some sense shortcomings of the D-Bus configuration scheme, since developers of a specific D-Bus service don’t expect that their configuration file has a global influence. A similar issue exists for logrotate where settings in drop-in configuration files in “/etc/logrotate.d” can influence global settings that affect the complete system. This can lead to hard to find bugs in both cases, D-Bus and logrotate, because the outcome also depends on the order in which the configuration file snippets are parsed.

Legacy fontinst D-Bus service

Most of the KDE components that we have been requested to look into for the KDE6 release had already been reviewed by us in recent years. A few of them are legacy packages though, since they were already in stock when we introduced packaging restrictions for D-Bus and Polkit. At the time we didn’t have enough resources to check all of them in one go.

One such legacy component we encountered while looking into the KDE6 release was the “org.kde.fontinst.service” which is part of the “plasma6-workspace” package. What we found there is a single D-Bus method “org.kde.fontinst.manage” that actually multiplexes a whole range of sub-methods, based on a “method” string input parameter. This is bad design since it undermines the D-Bus protocol, and thus makes the individual method calls less visible and less manageable. This is reinforced by the fact that also only a single Polkit action is used to authenticate all the sub-methods. This way there is only an all-or-nothing setting for the various code paths that are hidden behind this single D-Bus method call.

The available sub-methods in this service nearly make up a generic file system I/O layer, especially when we remember that this service is running with full root privileges:

  • install: this can be used to copy arbitrary file paths to arbitrary locations, the new files end up with mode 0644.
  • uninstall: this allows to remove arbitrary file paths, as long as their parent directories have a writable bit set.
  • move: this allows to move arbitrary paths complete with new owner uid and group gid to arbitrary new locations.
  • toggle: this takes raw XML that also seems to specify font paths that are to be enabled or disabled.
  • removeFile: does what is says on the label; another way to remove files.
  • configure: saves modified font directories and invokes a small bash script fontinst_x11 that prepares font directories and triggers a font refresh at the X server.

The core business logic of the fontinst service should be managing system wide fonts provided in the system. To achieve this, ideally only the necessary high level logical operations should be offered like: Install a font from provided data, remove a system font by name. Copying, removing and moving arbitrary files is way outside of the scope of what this service is supposed to do.

The single Polkit action “org.kde.fontinst.manage” requires auth_admin_keep authorization by default i.e. anybody that wants to invoke this method needs to provide admin credentials. Still, if an admin decides to lower these requirements, because users should be able to e.g. install new fonts in the system, then this interface does not only allow that, but also allows to gain full root privileges by copying arbitrary files around (e.g. by creating a new “/etc/shadow” file).

This service requires a larger redesign. KDE upstream was not able to come up with that in time for the KDE6 release. We hope that it will still happen though, as the API is in a rather worrying state.

Woes with “unexpected” Polkit Settings

The situation in the fontinst service regarding the auth_admin setting is a common pattern that we see when reviewing D-Bus services and Polkit actions. Developers believe that requiring auth_admin authentication for a Polkit action is enough to justify overly generic APIs or unsafe file system operations carried out as root. In some cases it might be justifiable to say that an action should never have weaker authentication requirements than auth_admin, since it otherwise causes uncontrollable security issues. One should not forget that Polkit is a configurable authentication framework, though. There are default settings shipped by applications, but system integrators and admins are allowed to change these requirements.

The (open)SUSE Linux distributions are the only ones we know of, that offer a defined mechanism for admins to override the Polkit defaults for individual actions via profiles and overrides. This works via the polkit-default-privs package. Our experience with this shows that upstream developers mostly neither consider the security consequences of lowering the Polkit authentication requirements, nor test what happens when the authentication requirements are raised for hardening purposes. Raised authentication requirements lead to additional password prompts, and some applications implement workflows involving Polkit actions that lead to very unfortunate behaviour in such cases.

A common example of this is a package manager like Flatpak, that attempts to acquire Polkit authentication for a repository refresh action upon login into a graphical session. The developers only test this with the default yes Polkit authentication requirement, which makes this authentication process invisible to users. When raising this to auth_admin, then suddenly a password prompt pops up during login and users are confused and annoyed. There are ways to deal with this: for example, services using Polkit can ask it whether an action can be authorized without user interaction. If this is not the case, then a package manager could choose not to refresh repositories just now. Also multiple actions can be authenticated in groups using the “org.freedesktop.policykit.imply” annotation to avoid multiple password prompts coming up for a single workflow.

It is understandable that the configuration management of many different Polkit configurations is hard to test for upstream developers. Increased awareness of the general problems in this area would help to avoid these issues in the first place. It seems that developers just want to “cram in” authentication into their software, though, and stop thinking about it once they’re done. Granted, Polkit and D-Bus are far from simple when you’re new to them. Still, every authentication procedure should be given careful thought. The take home lessons for developers implementing Polkit should be:

  • Polkit is a configurable authentication framework and the settings intended by developers might not be what actually happens during runtime.
  • When modelling Polkit actions, one should take advantage of the possibility to make them fine grained, to allow users to fine tune the requirements for individual activities.
  • Each Polkit authorization that happens in an application should be given some thought in both directions: what happens if the authentication requirement is lowered and what happens if it is raised?
  • Another aspect that hasn’t been discussed yet is the topic of authentication messages shown to the user. They should clearly state what exactly is being authorized in a form that non-technical users can understand. Polkit also supports placeholders in messages to fill in runtime information, like a file that is being operated on. Sadly, this feature is used very rarely in practice.

Problematic File System Operations in sddm-kcm6

This component is a KDE Configuration Module (KCM) for the SDDM display manager. It contains a D-Bus service “org.kde.kcontrol.kcmsddm.conf”. We reviewed it already in the past and did so again for the KDE6 release. The service has two major problems, discussed in the following sections.

Unsafe Operations on File System Paths Provided by the Unprivileged D-Bus Client

Multiple of the D-Bus methods provided by the sddm-kcm6 KAuth helper expect file system paths as input parameters. Such passing of paths to privileged D-Bus services is another problematic pattern that is often encountered. In the openConfig() function, the provided path to a SDDM theme configuration file will be created by the helper, if necessary. If it already exists, then a chmod() of the path to mode 0600 is performed, which is also following symlinks. To see how this can be problematic, consider what happens if “/etc/shadow” is passed as theme configuration path.

Operating as root, on files that are under control of an unprivileged user, is notoriously hard to get right, and requires careful use of lower level system calls. Often developers aren’t even aware of this problem. KDE components have had a number of problems in this area in the past. We believe this has deeper roots, namely in the design of the Qt framework’s file system API, which on the one hand doesn’t allow full control over the lower level system calls (owed to the fact that Qt is also a platform abstraction layer), and on the other hand does not document exactly what can be expected of its APIs in this regard. Furthermore the Qt framework itself isn’t aware of the fact that it runs as root, possibly operating on files owned by other users. The Qt libraries are designed for implementing feature rich GUI applications and don’t really consider handling untrusted input, operating with raised privileges and crossing privilege boundaries.

An elegant way to avoid the path access issue in the first place is by not passing file paths, but already opened file descriptors over D-Bus. This is possible since D-Bus uses UNIX domain sockets internally, and they can be used to pass file descriptors. So instead of passing a string from client to service suggesting “Open this file, trust me, it’s fine”, the client passes a file descriptor, opened using its own low privileges, to the privileged service. With this, many path access issues are gone in an instant. There are cases that still require care, however, for example if recursive file system operations need to be carried out.

Unfortunately the KAuth framework used by KDE shows a limitation in this area. Since the KAuth helper’s D-Bus API only transfers binary blobs that result from serializing QVariantMap, there is currently no possibility to pass an open file descriptor.

Changes in configuration files owned by the sddm service user

The other problem is not found in the D-Bus API, but in the implementation of the sync() and reset() D-Bus methods. Once any input parameters from the client are processed, the helper operates in the home directory belonging to the sddm service user. Here is some condensed code taken from the reset() and sync() functions:

// from SddmAuthHelper::reset()
QString sddmHomeDirPath = KUser("sddm").homeDir();
QDir sddmConfigLocation(sddmHomeDirPath + QStringLiteral("/.config"));
QFile::remove(sddmConfigLocation.path() + QStringLiteral("/kdeglobals"));
QFile::remove(sddmConfigLocation.path() + QStringLiteral("/plasmarc"));
QDir(sddmHomeDirPath + "/.local/share/kscreen/").removeRecursively();
// from SddmAuthHelper::sync()
QString sddmHomeDirPath = KUser("sddm").homeDir();

QDir sddmCacheLocation(sddmHomeDirPath + QStringLiteral("/.cache"));
if (sddmCacheLocation.exists()) {
    sddmCacheLocation.removeRecursively();
}

QDir sddmConfigLocation(sddmHomeDirPath + QStringLiteral("/.config"));

if (!args[QStringLiteral("kscreen-config")].isNull()) {
    const QString destinationDir = sddmHomeDirPath + "/.local/share/kscreen/";
    QSet<QString> done;
    copyDirectoryRecursively(args[QStringLiteral("kscreen-config")].toString(), destinationDir, done);
}

A compromised sddm service user can exploit these operations to its advantage:

  • it can cause a denial-of-service by e.g. placing directory symlinks to have the D-Bus service operate in completely different file system locations. This attack is limited though, since the final path components used in removal calls need to match, like kscreen.
  • it can cause the “kscreen-config” to be copied to arbitrary locations by placing a symlink in “~/.local/share/kscreen”.

To make these operations safe, it would be best to temporarily drop privileges to the sddm user.

Going Forward from Here

KDE upstream was not able to come up with a redesign of this D-Bus service in time for the KDE6 release. In this instance, the unsafe operations in the sddm user’s home directory would formally even justify assignment of a CVE. Since all the D-Bus methods are guarded by auth_admin Polkit authentication requirements, the issues can at least not be exploited in default installations.

KWalletManager: Pseudo-Authentication to Protect the Configuration

KWalletManager is KDE’s password manager. It features a GUI and, as one would expect, runs in the context of the graphical user session of a logged-in user. It ships a “savehelper” service that offers a single D-Bus method “org.kde.kcontrol.kcmkwallet5.save”. So what does a service helper running as root need to save here? Let’s look at the implementation:

ActionReply SaveHelper::save(const QVariantMap &args)
{
    Q_UNUSED(args);
    const qint64 uid = QCoreApplication::applicationPid();
    qDebug() << "executing uid=" << uid;
    return ActionReply::SuccessReply();
}

Turning this piece of code carefully to all sides will lead to the insight that it does nothing. We asked upstream to remove this unused helper, but we’ve been told that this is not a mistake, but on purpose. They want to protect against the following attack scenario: a user leaves their computer alone and unlocked, a random person gets by and, of all things, wants to change KWalletManager’s settings. To prevent this from happening, the GUI is asking the service helper to authenticate the action requiring Polkit’s auth_self authorization, and doesn’t continue if this fails.

This cannot stop a real attacker, though, since the KWalletManager configuration is stored in the unprivileged user’s home directory and can still be edited directly, or using a modified version of KWalletManager that simply does not ask for this authentication. Not to talk about all the other things that an attacker could do in such a situation. So where should one draw a line to stop? We don’t even see this as a hardening, it is fake security and confusing. If such a fake authentication is really needed then at least a way should be found to implement it, without requiring an authentication helper running as root that does nothing. Upstream seems to disagree, but we asked our packagers to remove this logic from our packaging via patches.

Improvements in DrKonqi

DrKonqi is KDE’s crash handling utility. These days, it interacts with systemd-coredump to access core dumps of applications. Our previous 2022 review of it led to a finding in systemd-coredump itself. In the meantime DrKonqi obtained additional D-Bus service logic to copy a private core dump (e.g. from a process that was running as root) into the session of an unprivileged user for analysis.

The implementation of this is unusual for a KDE component in so far as it doesn’t rely on KAuth: it directly uses the Qt framework’s D-Bus and Polkit facilities. The likely reason for this is the shortcoming of KAuth with regard to passing file descriptors, as discussed above. The single excavateFromToDirFd() D-Bus method actually accepts a file descriptor. It is supposed to be a file descriptor referring to a directory under control of the unprivileged caller, where the selected core dump is to be copied to. Even though this means that DrKonqi cannot benefit from the common framework features of KAuth, it is security-wise a good example of how to improve the robustness of a D-Bus service running as root and operating in the file system.

Unfortunately, even with file descriptors issues can arise, as this example also shows. The permission handling for directories is different from regular files. Directories generally can only be opened in read-only mode (O_RDONLY). Write permissions are only checked at the time a write attempt is made, like when calling renameat() in the case of the DrKonqi helper. This is too late. The unprivileged caller can open just any directory it has read access for and pass it to the D-Bus service. The D-Bus service running as root will now happily create new files in the directory even if the caller doesn’t have any write permissions for it.

There is a constructive discussion discussion going on with upstream that led to various improvements in detail in this D-Bus service that are about to be merged. The issue with the dir file descriptor was only found late in the process, but hopefully a solution for the problem will be found soon.

Conclusion

D-Bus and Polkit have their share of complexities that need to be understood and managed well. This is important as a defense in depth measure even beyond the local security of a Linux system. Putting additional layers on top, like in the KAuth framework, can cause long-term problems, as can be seen from the lack of support for passing file descriptors with the current KAuth API.

It was helpful that our KDE packagers and upstream approached us early about the KDE6 release candidate and the changes it introduces. In some areas, like the badly generated D-Bus KAuth configuration files, upstream quickly reacted and applied fixes, thus avoiding that the problematic code was ever released in a production version of KDE6. In other areas, like the legacy fontinst D-Bus service or the sddm-kcm D-Bus service, the complexity of fixing API issues has obviously been too high for upstream to come up with something better in time. We decided not to ask for CVE assignments for the findings in these services, since the attack vectors are not reachable to regular users in the default Polkit configuration.

By now most KDE6 packages should have reached openSUSE Tumbleweed and can be used in production.

References

Change History

2024-04-05 Minor spelling fixes; inserted an introductory paragraph to Unsafe Operations in sddm-kcm6.

Sat, Mar 30th, 2024

Nintendo DS Lite Upper LCD Replacement

This is not a “how-to” but rather a commentary on this task. My oldest son complained of a damaged upper screen on his Nintendo DS Lite so I thought, “meh, how hard can it be?” Without doing an real research on it, I purchased the replacement screen, watched a couple YouTube videos and I started … Continue reading Nintendo DS Lite Upper LCD Replacement

Fri, Mar 29th, 2024

openSUSE Tumbleweed – Review of the week 2024/13

Dear Tumbleweed users and hackers,

What a week! We all were looking forward to a short week just before the Easter weekend and a long break. Things just never are, as they are expected to be, right? You have “only” received 4 snapshots this week (0325, 0326, 0327, and 0328) – and, as happens very rarely, some updates in the update channel (this should indicate to you it is important enough for us to side-track the already fast release process).

The most relevant changes this week were:

  • Mesa 24.0.3
  • KDE Gear 24.02.1
  • emacs 29.3
  • Shadow 4.15.1
  • Mozilla Firefox 124.0.1
  • KDE Plasma 6.0.3
  • LibreOffice 24.2.2
  • TeXLive 2024
  • Qt 6.6.3
  • cURL 8.7.1
  • xz 5.6.1.revertto5.4 (version 5.4, but with a version tag > 5.6.1 for users that wrongly would not use zypper dup – we wanted to be sure). Please see https://news.opensuse.org/2024/03/29/xz-backdoor/ and upgrade SOON (at least liblzma5, then reboot)

For some regions, there is a long weekend ahead – so expect no / few snapshots until early next week. For snapshot 0328, Ring0 has been completely bootstrapped (as the attack vectors for xz were not fully known, we went the safest route) and for 0329 all of Tumbleweed rebuilt against that new base; Ezpect that snapshot to appear ‘large’ (even though many packages will not be different). The relevant changes to come to you during the next days/week include:

  • Python 3.9 module removal (the bootstrap rebuild was a good excuse, as that removal would have required OBS internal rebuild strategy anyway – so instead of doing it twice, we pulled that change forward into 0329 – I mentioned that removed for a few weeks already)
  • Linux kernel 6.8.2
  • Linux LTS Kernel 6.6.23
  • dbus-broker: no progress this week
  • libxml 2.12.x: slow/no progress
  • GCC 14: phase 2: use gcc14 as the default compiler

Unbreakable Self-Adjusting Vertical Laptop Holder

I requested a new monitor in the office because the one I had was developing a cluster of vertical lines running through it. I actually got what I asked for, an LG DualUp display that is essentially like having two, 1440p monitors stacked on top of one another without the bezel. It was essentially perfect … Continue reading Unbreakable Self-Adjusting Vertical Laptop Holder

openSUSE addresses supply chain attack against xz compression library

openSUSE maintainers received notification of a supply chain attack against the “xz” compression tool and “liblzma5” library.

Background

Andres Freund reported to Debian that the xz / liblzma library had been backdoored.

This backdoor was introduced in the upstream github xz project with release 5.6.0 in February 2024.

Our rolling release distribution openSUSE Tumbleweed and openSUSE MicroOS included this version between March 7 and March 28.

SUSE Linux Enterprise and openSUSE Leap are built in isolation from openSUSE Tumbleweed. Code, functionality and characteristics of Tumbleweed are not automatically introduced in SUSE Linux Enterprise and/or openSUSE Leap. It has been established that the malicious file introduced into Tumbleweed is not present in SUSE Linux Enterprise and/or openSUSE Leap.

Impact

Current research indicates that the backdoor is active in the SSH Daemon, allowing malicious actors to access systems where SSH is exposed to the internet.

As of March 29, reverse engineering of the backdoor is still ongoing.

Mitigations

openSUSE Maintainers have rolled back the version of xz on Tumbleweed on March 28 and have released a new Tumbleweed snapshot (20240328 or later) that was built from a safe backup.

The reversed version is versioned 5.6.1.revertto5.4 and can be queried with rpm -q liblzma5.

User recommendation

For our openSUSE Tumbleweed users where SSH is exposed to the internet, we recommend installing fresh, as it’s unknown if the backdoor has been exploited.

Due to the sophisticated nature of the backdoor an on-system detection of a breach is likely not possible.

Also rotation of any credentials that could have been fetched from the system is highly recommended. Otherwise, simply update to openSUSE Tumbleweed 20240328 or later and reboot the system.

Thu, Mar 28th, 2024

openSUSE Tumbleweed Monthly Update - March

Welcome to the monthly update for openSUSE Tumbleweed for March 2024. This month provided several anticipated updates for the rolling release.

Before getting in the package updates, know that this blog aims to provide readers an overview of the key changes, improvements and issues addressed in openSUSE rolling release throughout the month. Should readers desire a more frequent amount of information about snapshot updates, readers are encouraged to subscribe to the openSUSE Factory mailing list.

Let’s get started.

New Features and Enhancements

  • Linux Kernel: Versions for the month of March progressed update version 6.8.1. These updates enhance system stability, security and hardware compatibility. Snapshot 20240319 that moved the kernel from 6.7.9 to 6.8.1 did the following:
    • Patches addressed Register File Data Sampling (RFDS) microarchitectural vulnerabilities CVE-2023-28746. The patch includes mitigation measures such as exporting to guests in KVM/x86 environments and adds new documentation. There was a patch to disable KVM mitigation when the X86_FEATURE_CLEAR_CPU_BUF is set.
    • A notable reversion is the removal of code for inode_cache and recovery mount options from Btrfs, following an issue. Fixes related to Btrfs, such as addressing a race condition when detecting Delayed Allocation ranges during fiemap.
    • The updates involve significant configuration changes for arm architectures (armv6hl, armv7hl, and arm64). The updates mirror option values across different architectures and include new configurations for hardware support, such as various PINCTRL (Pin Control), GPIO (General-Purpose Input/Output), VIDEO, DRM (Direct Rendering Manager) and SND_SOC (Sound System on Chip) settings.
  • Plasma 6: Find the article on news.opensuse.org
  • GNOME 46: Find the article on news.opensuse.org
  • systemd: From version 254.9 to 255.4, the updated provided the following:
    • Specific issues have been either rebased or removed if they’ve become part of the core version 255 updates. This indicates a significant step towards maintaining consistency with upstream developments while also ensuring the stability and reliability of systemd functionalities within penSUSE.
  • A clear emphasis has been placed on enhancing the testing framework within the systemd package to ensure the reliability of bootloader installation processes during testing phases. Read more info about the systemd-bootl integration.
  • libzypp 17.32.0
    • Introduction of a new resolver option ‘removeOrphaned’ for dist-upgrade processes to enhance package management
    • Fixes applied to vsftpd.conf addressing issues where SUSE and Fedora use different defaults.
    • Security Updates: Modification to avoid using the deprecated OPENSSL_config in the Digest section, enhancing security practices.
    • Introduction of ProblemSolution::skipsPatchesOnly overload to improve patch management processes.
    • Removal of HTTPS->HTTP redirection exceptions for download.opensuse.org, reinforcing security and integrity in download processes.
  • zypper 1.14.70:
    • Integration of a new option --remove-orphaned to remove all orphaned packages during a system upgrade.
    • Improved user interface indicating active dry-run/download-only options at the commit prompt, enhancing user experience and clarity.
    • Setting of libzypp shutdown request signal upon Ctrl+C to improve responsiveness and control.
  • LLVM 18:
    • The patches llvm-do-not-install-static-libraries.patch and llvm-normally-versioned-libllvm.patch have been rebased to align with the new version, addressing specific distribution and library concerns.
    • Modification to prefer ld.bfd over other linkers to achieve a Transparent Huge Pages (THP)-compatible section layout, optimizing memory management and performance.
  • shadow: Updates to version 4.15.1
    • Resolved an issue causing unwarranted error messages about unknown login.defs configuration options and implements checks for file descriptor omission to improve security and reliability
    • The shadow-4.15.0-fix-definition.patch has been updated to address the erroneous error messages regarding configuration options,
    • Improved linking with libdl for better dynamic library handling.
      • Revised the shadow-login_defs-unused-by-pam.patch to ensure continued compatibility and effectiveness.

Bug Fixes

  • Mozilla Firefox 124.0.1: Had multiple Common Vulnerabilities and Exposures fixes. These included CVE-2024-29943, which an attacker was able to perform an out-of-bounds read or write on a JavaScript object by fooling range-based bounds check elimination, and related CVE-2024-29944. There were 12 more CVEs addressed in the update from snapshot 20240326
  • redis 7.2.3: The update provides a fix for CVE-2023-41056 that caused memory issues and security risks.
  • python311: CVE-2024-0450 was added to the changelog due to a revert use of automated tool scripts.
  • Linux Kernel 6.8.1: CVE-2023-28746 was related to microarchitectural vulnerabilities as mentioned above. Expat 2.6.2: This CVE-2024-28757 fix prevent a vulnerable attacks that overloads it with XML entities, especially when using external parsers created in a certain way.
  • opensc 0.25.0: Has a fix for CVE-2023-5992 where PKCS#1 encryption padding removal was not implemented as side-channel resistant and fixes CVE-2024-1454 that requires physical access and special device related to its AuthentIC driver that happens when setting up new cards.
  • libvirt 10.1.0: The update brings a fix for CVE-2024-1441 that has an off-by-one error that could allow Denial of Service via crafted data to crash daemon.
  • Unbound 1.19.2: Provides a fix for CVE-2024-1931, which could lead to a Denial of Service from infinite loop in Extended DNS Error record trimming.
  • graphviz: Exploitability for CVE-2023-46045 may be uncommon because this file is typically owned by root, but is related to an out-of-bounds read via a crafted config6a file. A welcoming fix was provided.
  • openjpeg2 2.5.2: With CVE-2021-3575, an attacker could use this to execute arbitrary code with the permissions of the application compiled against openjpeg.

Conclusion

March 2024 brought numerous updates for openSUSE Tumbleweed systems. Besides Plasma and GNOME desktop environments, there were improvements across systemd, libzypp, LLVM and more. Other significant upgrades during the month included updates to bind, CMake, KDE Gear 24.02.1, Mesa, qemu and more. For those Tumbleweed users that want to contribute, subscribe to the openSUSE Factory mailing list. The openSUSE team encourages users to continue participating through bug reports, feature suggestions and discussions.

Contributing to openSUSE Tumbleweed

Your contributions and feedback make openSUSE Tumbleweed better with every update. Whether reporting bugs, suggesting features, or participating in community discussions, your involvement is highly valued.

Wed, Mar 27th, 2024

Alerting on One Identity Cloud PAM Essentials logs using syslog-ng

One Identity Cloud PAM Essentials is the latest security product by One Identity. It provides asset management as well as secure and monitored remote access for One Identity Cloud users to hosts on their local network. I had a chance to test PAM Essentials while still in development. While there, I also integrated it with syslog-ng.

From my previous blog, you could learn what PAM Essentials is, and how you can collect its logs using syslog-ng. This blog will show you how to work with the collected log messages and create alerts when somebody connects to a host on your local network using PAM Essentials.

https://www.syslog-ng.com/community/b/blog/posts/alerting-on-one-identity-cloud-pam-essentials-logs-using-syslog-ng

syslog-ng logo

Tue, Mar 26th, 2024

Installation guide for warewulf4

Warewulf

Preface

In High Performance Computing (HPC), computing tasks are usually distributed among many compute threads which are spread across multiples cores, sockets and machines. These threads are tightly coupled together. Therefore, compute clusters consist of a number of largely identical machines that need to be managed to maintain a well-defined and identical setup across all nodes. Once clusters scale up, there are many scalability factors to overcome. Warewulf is there to address this ‘administrative scaling’.

Warewulf is an operating system-agnostic installation and management system for HPC clusters.
It is quick and easy to learn and use as many settings are pre-configured to sensible defaults. Also, it still provides the flexibility allowing fine tuning the configuration to local needs. It is released under the BSD license, its source code is available at https://github.com/warewulf/warewulf. This is where the development happens as well.

This article gives an overview on how to set up Warewulf on openSUSE Leap 15.5 or openSUSE Tumbleweed.

Installing Warewulf

Compute clusters consist of at least one management (or head) node which is usually multi-homed connected both to an external network and a cluster private network, as well as multiple compute nodes which reside solely on the private network. Other private networks dedicated to high speed tasks like RDMA and storage access may exist as well. Warewulf gets installed on one of the management nodes of a cluster to manage and oversee the installation and management of the compute nodes. To install Warewulf on a cluster which is running openSUSE Leap 15.5 or openSUSE Tumbleweed, simply run:

zypper install warewulf

This package seamlessly integrates into a SUSE system and should therefore be preferred over packages provided on Github.

During the installation, the actual network configuration is written to /etc/warewulf/warewulf.conf. These settings should be verified, as for multi homed hosts a sensible pre-configuration is not always possible.

Check /etc/warewulf/warewulf.conf for the following values:

ipaddr: 172.16.16.250
netmask: 255.255.255.0
network: 172.16.16.0

where ipaddr should be the IP address of this management host. Also check the values of netmask and network - these should match this network.

Additionally, you may want to configure the IP addresse range for dynamic/unknown hosts:

dhcp:
  range start: 172.16.26.21
  range end: 172.16.26.50

If the ISC DHCP server (dhcpd) is used (default on SUSE), make sure the value of DHCPD_INTERFACE in the file /etc/sysconfig/dhcpd has been set to the correct value.

You are now ready to start the warewulfd service itself which delivers the images to the nodes:

systemctl enable --now warewulfd.service

Now wwctl can be used to configure the the remaining services needed by Warewulf. Run:

wwctl configure --all

which will configure all Warewulf related services.

To conveniently log into compute nodes, you should now log out of and back into the Warewulf host, as this will create an ssh key on the Warewulf host which allows password-less login to the compute nodes. Note however, that this key is not yet pass-phrase protected. If you require protecting your private key by a pass phrase, it is probably a good idea to do so now:

ssh-keygen -p -f $HOME/.ssh/cluster

Adding nodes and profiles to Warewulf

Warewulf uses the concept of profiles which hold the generalized settings of the individual nodes. It comes with a predefined profile default, to which all new node will be assigned, if not set otherwise. You may obtain the values of the default profile with:

wwctl profile list default

Now, a node can be added with the command assigning it an IP address:

wwctl node add node01 -I 172.16.16.101

if the MAC address is known for this node, you can specify this as well:

wwctl node add node01 -I 172.16.16.101 -H cc:aa:ff:ff:ee

For adding several nodes at once you may also use a node range, e.g.

wwctl node add node[01-10] -I 172.16.16.101

This will add the nodes with ip addresses starting at the specified address and incremented by Warewulf.

Importing a container

Warewulf uses a special 1 container as base to build OS images for the compute nodes. This is self contained and independent of the operating system installed on the Warewulf host.

To import an openSUSE Leap 15.5 container use the command

wwctl container import docker://registry.opensuse.org/science/warewulf/leap-15.5/containers/kernel:latest leap15.5 --setdefault

This will import the specified container for the default profile.

Alternative container sources

Alternative containers are available from the openSUSE registry under the science project at:

https://registry.opensuse.org/cgi-bin/cooverview?srch_term=project%3D%5Escience%3A

or from the upstream Warewulf community repository:

https://github.com/orgs/warewulf/packages?repo_name=warewulf-node-images

It is also possible to import an image from a local installation into a directory (chroot directories) by using the path to this directory as argument for wwctl import.

Booting nodes

As a final preparation you should rebuild the container image, now, by running:

wwctl container build leap15.5

as well as all the configuration overlays with the command:

wwctl overlay build

just in case the build of the image may have failed earlier due to an error. If you didn’t assign a hardware address to a node before, you should set the node into the discoverable state before powering it on. This is done with:

wwctl node set node01 --discoverable

Also you should run:

wwctl configure hostlist

to add the new nodes to the file /etc/hosts. Now you should make sure that the node(s) will boot over PXE from the network interface connected to the specified network and power on the node(s) to boot into assigned image.

Additional configuration

The configuration files for the nodes are managed as Golang text templates. The resulting files are overlayed over the node images. There are two types of overlays depending on how they are added to the compute node:

  • the system overlay which is ‘baked’ into the image during boot as part of the wwinit process.
  • the runtime overlay which is updated on the nodes on a regular base (1 minute per default) via the wwclient service.

In the default configuration the overlay called wwinit is used as system overlay. You may list the files in this overlays with the command:

wwctl overlay list wwinit -a

which will show a list of all the files in the overlays. Files ending with the suffix .ww are interpreted as template by Warewulf, the suffix is removed in the rendered file. To inspect the content of an overlay file use the command:

wwctl overlay show wwinit /etc/issue.ww

To render the template using the values for node01 use:

wwctl overlay show wwinit /etc/issue.ww -r node01

The overlay template itself may be edited using the command:

wwctl overlay edit wwinit /etc/issue.ww

Please note that after editing templates, the overlays aren’t updated automatically and you should trigger a rebuild with the command:

wwctl overlay build

The variables available in a template can be listed with

wwctl overlay show debug /warewulf/template-variables.md.ww

Modifying the container

The node container is a self contained operating system image. You can open a shell in the image with the command:

wwctl container shell leap15.5

After you have opened a shell, you may install additional software using zypper.

The shell command provides the option --bind which allows mounting arbitrary host directories into the container during the shell session.

Please note that if a command exits with a non-zero status, the image won’t be rebuilt automatically. Therefore, it is advised to rebuild the container with:

wwctl conainer build leap15.5

after any change.

Network configuration

Warewulf allows configuring multiple network interfaces for the compute nodes. Therefore, you can add another network interface for example for infiniband using the command:

wwctl node set node01 --netname infininet -I 172.16.17.101 --netdev ib0 --mtu 9000 --type infiniband

This will add the infiniband interface ib0 to the node node01. You can now list the network interfaces of the node:

wwctl node list -n

As changes in the settings are not propagated to all configuration files, the node overlays should be rebuilt after this change by running the command:

wwctl overlay build

After a reboot, these changes will be present on the nodes; in the above case the Infiniband interface will be active on the node.

A more elegant way to get the same result is to create a profile to hold those values which are identical for all interfaces. In this case, these are mtu and netdev. Create a new profile for an Infiniband network using the command:

wwctl profile add infiniband-nodes --netname infininet --netdev ib0 --mtu 9000 --type infiniband

You may now add this profile to a node and remove the node specific settings which are now part of the common profile by executing:

wwctl node set node01 --netname infininet --netdev UNDEF --mtu UNDEF --type UNDEF --profiles default,infiniband-nodes

To list the data in a profile use the command:

wwctl profile list -A infiniband-nodes

Secure Boot

Switch to grub boot

By default, Warewulf boots nodes via iPXE, which isn’t signed by SUSE and can’t be used when secure boot is enabled. In order to switch to grub as the boot method you must add or change the following value in /etc/warewulf/warewulf.conf

warewulf:
  grubboot: true

After this change, you will have to reconfigure dhcpd and tftp executing:

wwctl configure dhcp
wwctl configure tftp

and rebuild the overlays with the command:

wwctl overlay build

Also make sure that the packages shim and grub2-x86_64-efi (for x86-64) or grub2-arm64-efi (for aarch64) are installed in the container. shim is required by secure boot.

Cross product secure boot

With secure boot is enabled on the compute nodes, if you need to boot different products, you need to make sure that the compute nodes boot with the so-called ‘http’ boot method: For secure boot the signed shim needs to match the signature of the other pieces of the boot chain - including the kernel. However, different products will have different sets of signatures in their boot chain. The ‘http’ boot method is handled by warewulfd. This will look up the image to boot and pick the right shim from the image to deploy to a particular node. Therefore, you need to make sure, that the node container contains the shim package. The default boot method will extract the initial shim for PXE boot from the host running the warewulfd server. Note, however, that the host system shim will also be used for nodes which are in the discoverable state and subsequently have no hardware address assigned, yet.

Disk management

It is possible to manage the disks of the compute nodes with Warewulf. Here, Warewulf itself doesn’t manage the disks, but creates a configuration and service files for ignition to do this job.

Prepare container

As ignition and its dependencies aren’t installed in most of the containers, you should install the packages ignition and gptfdisk in the container.

wwctl container exec <container_name> zypper -n in -y ignition gptdisk

Add disk to configuration

Warewulf boots ephemeral systems, thus there is no need for local disk storage. Still, local disk storage may me useful to have, for instance as scratch storage for computational tasks. Warewulf is capable of setting up local disk storage. For this, it is necessary to configure the involved entities:

  • physical storage device(s) to be used
  • partition(s) on the disks
  • filesystem(s) to be used

Warewulf doesn’t manage these entities itself, but creates a configuration and service files for ignition to perform this task. Therefore, you need to make sure to install ignition and gptfdisk on the compute node. Open a shell in the container and run:

zypper -n in -y zypper install ignition gptfdisk

Disks

The path to the device e.g. /dev/sda must be used for diskname. The only valid configuration option for disks is diskwipe, which should be self-explanatory.

Partitions

The partname is the name to the partition which iginition uses as the path for the device files, e.g. /dev/disk/by-partlabel/$PARTNAME.

Additionally, the size and number of the partition need be specified for all but the last partition (the one with the highest number) in which case this partition will be extended to the maximal size possible.

You should also set the boolean variable --partcreate so that a parition is created if it doesn’t exist.

Filesystems

Filesystems are defined by the partition which contains them, so the name should have the format /dev/disk/by-partlabel/$PARTNAME. A filesystem needs to have a path if it is to be mounted, but its not mandatory.

Ignition will fail if there is no filesystem type defined.

Examples

You can add a scratch partition with

wwctl node set node01 \
  --diskname /dev/vda --diskwipe \
  --partname scratch --partcreate \
  --fsname scratch --fsformat btrfs --fspath /scratch --fswipe

This will be the only (and last) partition, therefore it does not require a size. To add another partition as a swap partition, you may run:

wwctl node set n01 \
  --diskname /dev/vda \
  --partname swap --partsize=1024 --partnumber 1 \
  --fsname swap --fsformat swap --fspath swap

This adds the partition number 1 which will be placed before the scratch partition.

  1. This container is special only in that it is bootable, i.e. it contains a kernel and an init-implementation (systemd). 

Mon, Mar 25th, 2024

GNOME Arrives in openSUSE Releases

March has been an exciting month for openSUSE Tumbleweed users as GNOME 46 made its way into the rolling release like KDE’s Plasma 6 did a few weeks ago.

The GNOME users and developers not only get the upgrade in the rolling release but in the Aeon Desktop derivative. The release in the Slowroll distribution will likely see an update between April 2 and April 14.

GNOME’s version 46 codenamed “Kathmandu” pays homage to the contributions from GNOME.Asia 2023 organizers and has significant improvements and new features. A standout feature in GNOME 46 is the new global search functionality within the files app. This feature enables users to search across all configured locations directly and an addition of filters by file type and modification date further refine the tool.

The files app had a major revamp that allows for instant view switching between list and grid modes. It also had some other minor improvements such as enhanced network discovery and starred favorites in grid view, which amplified file management efficiency.

A new remote login option enhances GNOME’s remote desktop capabilities, which allows for improved configuration and user experience from the remote side.

Accessibility has seen significant advancements, especially with the Orca screen reader, which now includes a new sleep mode and system status reports. Additionally, there’s an increase in high contrast mode consistency and new settings for clearer switch toggling.

Other changes include the settings app, which has been reorganized and was updated for easier navigation. The new touchpad settings is noteworthy and includes configurations for secondary clicks that aims to enhance user interaction and convenience.

System updates include refreshed user avatars, improved notifications, and tap-to-click enabled by default. The Software app now features verified badges for Flathub apps, and both the extensions and calendar apps have been redesigned for better usability and aesthetics.

Beyond user-facing features, GNOME 46 introduces deep technical enhancements. These include performance and resource usage optimizations, security enhancements, rendering improvements and experimental support for variable refresh rates to improve video performance under certain conditions.

With its comprehensive updates and new features of GNOME 46, people should either be doing a zypper dup or transactional-update to get the latest.

LocalSend | Easily Share Files Between Nearby Devices

LocalSend is a the AirDrop for the rest of us. The ability to easily send files to other computers or systems that are local to your network. This is also cross platform, so whether you are on Linux, Windows, macOS, Android, or iOS, this will work for you. It really couldn’t be much easier. Bottom … Continue reading LocalSend | Easily Share Files Between Nearby Devices