Wed, Apr 3rd, 2024

dnf5daemon-server: Incomplete fix of CVE-2024-1929 (CVE-2024-2746)

Table of Contents

1) Introduction

CVE-2024-1929 that we previously reported for the dnf5 D-Bus component has not been completely fixed. This post deals with the remaining issue we discovered.

2) Unsafe Configuration Item “reposdir” in Whitelist

The problem with CVE-2024-1929 was that the dnf5 D-Bus daemon accepted arbitrary configuration parameters from unprivileged users, which allowed a local root exploit by tricking the daemon into loading a user controlled “plugin”. All of this happened before Polkit authentication was even started.

The original bugfix consists of a whitelist of configuration items, that unprivileged users are allowed to override, when using the dnf5 D-Bus interface. While checking each of the whitelisted items, we found that the setting “reposdir” allows to specify the path to an arbitrary directory, in which repository configuration files (*.repo) will be processed by the privileged dnf5 daemon.

The dnf5 library code does not check whether non-root users control the directory in question. The code does check for file type and filename extension of contained files; it follows symlinks and is subject to a race condition, however:

    std::filesystem::directory_iterator di(dir_path, ec);
    std::vector<std::filesystem::path> paths;

    for (auto & dentry : di) {
        auto & path = dentry.path();
        if (dentry.is_regular_file() && path.extension() == ".repo") {
            paths.push_back(path);
        }
    }

    std::sort(paths.begin(), paths.end());

    for (auto & path : paths) {
        create_repos_from_file(path);
    }

By the time the (checked) path is passed to create_repos_from_file(), the user controlling the directory can replace it with an arbitrary other file or symlink, thereby tricking the library to operate on arbitrary file types and file paths.

On one hand, this poses a Denial-of-Service attack vector by making the daemon operate on a blocking file (e.g. named FIFO special file) or a very large file that causes an out-of-memory situation (e.g. /dev/zero). On the other hand, this can be used to let the daemon process privileged files like /etc/shadow. The file in question is parsed as an INI file. Error diagnostics resulting from parsing privileged files could cause information leaks, if these diagnostics are accessible to unprivileged users. In the case of libdnf5, no such user accessible diagnostics should exist, though.

Even more interestingly, a local attacker can place a valid repository configuration file in this directory. This configuration file allows to specify a plethora of additional configuration options. This makes various additional code paths in libdnf5 accessible to the attacker. This, and the possibility to configure arbitrary repositories, could very well allow further privilege escalation, although we did not investigate more deeply if and how this would be possible.

This follow-up issue confirms the sentiment expressed in our original report, that one has to be extremely careful about feeding untrusted input into the libdnf5 library, which is not designed to run in mixed security scope setups.

3) Bugfix and CVE Assignment

The bugfix simply consists of the removal of the “reposdir” entry from the whitelist of configuration items. Upstream release 5.1.17 contains the bugfix. The Red Hat security team assigned CVE-2024-2746 to track this incomplete fix of CVE-2024-1929.

4) Discovery Process

We noticed the incomplete fix only at a late time, when our openSUSE dnf5 package maintainer asked for the inclusion of the fixed package into openSUSE Tumbleweed. It is unfortunate that this happened too late to prevent an incomplete fix for CVE-2024-1929, and thus made a follow-up CVE assignment and coordinated release process necessary.

Since the original issues had been handled as part of a coordinated disclosure process, there should have been a review of the proposed patches before publication. Due to the circumstances of an early publication of the fixes, outside of the coordinated release process, there never was a defined point in time for us to actually review them. We aim to avoid such situations in the future by being more careful about reviewing patches, especially when no straightforward coordinated release process can be established with upstream.

5) Timeline

2024-03-11 We reported the issue to secalert@redhat.com.
2024-03-13 The discussion for the issue was moved to a new group of contacts involving the dnf5 developers.
2024-03-20 One of the dnf5 developers confirmed the issue and suggested dropping “reposdir” from the whitelist.
2024-03-20 Red Hat security assigned CVE-2024-2746 for the follow-up issue.
2024-03-26 Discussions about the coordinated release date took place, 2024-04-02 has been mentioned.
2024-04-02 Red Hat security informed us that they actually had 2024-04-03 in mind.
2024-04-03 Upstream published release 5.1.17 containing the bugfix.

6) References

Tue, Apr 2nd, 2024

The syslog-ng health check

Version 4.2 of syslog-ng introduced a healthcheck option to syslog-ng-ctl. It prints three syslog-ng-related metrics on screen – if it can reach syslog-ng, that is. You can use it from scripts to monitor the health of syslog-ng.

https://www.syslog-ng.com/community/b/blog/posts/the-syslog-ng-health-check

syslog-ng logo

3D Printed Whiteboard Marker Clips

I purchased a whiteboard at the request of my oldest son for his bedroom to help him be more organized or maybe just to get away with drawing on the wall with markers. Either way. The board came with a single marker clip and he wanted more clips for more colors and such. He also … Continue reading 3D Printed Whiteboard Marker Clips

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