https://bugs.kde.org/show_bug.cgi?id=522847
Bug ID: 522847
Summary: kwalletd6: use-after-move in
SecretServiceClient::retrieveCollection() returns null
on first lookup (G_IS_DBUS_PROXY assertion; item
watches not registered)
Classification: Frameworks and Libraries
Product: frameworks-kwallet
Version First 6.18.0
Reported In:
Platform: RedHat Enterprise Linux
OS: Linux
Status: REPORTED
Severity: normal
Priority: NOR
Component: general
Assignee: [email protected]
Reporter: [email protected]
CC: [email protected]
Target Milestone: ---
`SecretServiceClient::retrieveCollection()`
(`src/runtime/kwalletd/secretserviceclient.cpp`) reads a `std::unique_ptr`
after
moving it into the cache, so the **first** lookup of any collection returns
`nullptr` even though the collection was found and cached:
```cpp
if (QString::fromUtf8(label) == name) {
m_openCollections.insert(std::make_pair(name, std::move(colPtr))); //
colPtr moved-from
SecretCollection *collection = colPtr.get(); //
reads moved-from -> nullptr
return collection; //
returns null on a SUCCESSFUL find
}
```
`colPtr.get()` after `std::move(colPtr)` reads a moved-from `std::unique_ptr`,
which is guaranteed empty. Only the return value is wrong; the collection is
inserted into `m_openCollections`, so later lookups (cache hits) succeed. This
is
still present on current master (it was not touched by `f4443393`, which fixed
a
separate stale-list issue in `listCollections()` for Bug 512135).
Observed symptoms (user-visible)
On the affected system (kf6-kwallet 6.18.0, ksecretd backend, Plasma
6/Wayland):
- Directly measured: `kwalletd6` logs
`g_dbus_proxy_get_object_path: assertion 'G_IS_DBUS_PROXY (proxy)' failed` at
start-up — one line per wallet/collection (2 assertions with two wallets; 0
after the fix).
- `kwalletmanager` / `kwallet-query` show the wallets but not the items inside
them, and can report a wallet/folder as "not found", even though the secrets
exist and are retrievable through libsecret (`secret-tool search`) and
visible
in `busctl --user tree org.freedesktop.secrets`.
- Intermittent `org.freedesktop.DBus.Error.NoReply` when a client requests
`org.kde.kwalletd5` / `org.kde.kwalletd6`; the same binary run in the
foreground starts and stays up. Whether it happens depends on ksecretd's
state/timing at activation.
- Restarting kwalletd6 makes it work again for a while — consistent with the
start-up cache-warming described under Impact.
Consistent with existing reports of the same daemon misbehaving (very likely
the
same root cause surfacing differently): Bug 504014 (Chrome/Discord slow to load
due to kwallet failure) and the KeePassXC "wrongly asks to create a new
database"
class (Bug 512135 — whose `listCollections()` path was fixed in `f4443393`; the
`retrieveCollection()` path here can produce the same "wallet looks missing"
behaviour and is still unfixed).
Impact (mechanism)
- `watchCollection()` feeds the null collection into
`g_dbus_proxy_get_object_path()`, producing the assertion above, and the
`ItemChanged`/`ItemCreated`/`ItemDeleted` signal subscriptions are never
registered — so the KWallet API/GUI stop seeing item changes (the "shows
wallets but not items" symptom).
- Callers that reach a collection before it is cached receive `nullptr`; when
`KWalletD::openInternal()` does, it treats the wallet as missing.
The `SecretServiceClient` constructor pre-warms the cache by calling
`watchCollection()` for every collection at start-up, so whether a later caller
hits the bug depends on timing (was the Secret Service reachable at
construction;
was the collection created afterwards).
Steps to reproduce
1. On a system where kwalletd6 proxies onto a Secret Service provider
(ksecretd),
with at least one collection.
2. Free the `org.kde.kwalletd*` name (kwalletd6 is a `KDBusService::Unique`,
auto-activated service, so temporarily disable its `.service` activation)
and
run `/usr/bin/kwalletd6` in the foreground.
Actual result
One `g_dbus_proxy_get_object_path: assertion 'G_IS_DBUS_PROXY (proxy)' failed`
per collection at start-up.
Expected result
No assertion; `retrieveCollection()` returns the found collection.
Additional information
Verified on kf6-kwallet 6.18.0: stock `kwalletd6` emits **2** such assertions
(two collections); with the one-line fix below it emits **0**. A standalone
reproducer of the pattern (no D-Bus/Qt/libsecret) shows `buggy -> nullptr`,
`fixed -> valid pointer`, identical at `-O0`/`-O2`.
Fix (capture the pointer before the move):
cpp
SecretCollection *collection = colPtr.get();
m_openCollections.insert(std::make_pair(name, std::move(colPtr)));
return collection;
--
You are receiving this mail because:
You are watching all bug changes.