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.

Reply via email to