https://bugs.kde.org/show_bug.cgi?id=525021

            Bug ID: 525021
           Summary: kdeconnectd aborts when a client requests more than
                    ~990 distinct conversations within 30 seconds
    Classification: Applications
           Product: kdeconnect
      Version First 26.08.0
       Reported In:
          Platform: Other
                OS: Linux
            Status: REPORTED
          Severity: crash
          Priority: NOR
         Component: common
          Assignee: [email protected]
          Reporter: [email protected]
                CC: [email protected]
  Target Milestone: ---

kdeconnectd dies with a fatal GLib error when a client asks the conversations
D-Bus interface
for a large number of distinct conversation threads in a short time. On a phone
with 1731 SMS
threads this happens reliably as soon as a client requests all of them, which
is what any
client doing a one time backfill or building a local index will do.

Each requestConversation call for a thread the daemon has not been asked about
recently
allocates one eventfd inside kdeconnectd. Repeating the same thread ID costs
nothing. The
descriptor is released about 30 seconds later, so this is not a leak, but
inside that window
the count grows by one per distinct thread. The daemon starts with roughly 31
open descriptors
and RLIMIT_NOFILE is the usual soft limit of 1024, so the ceiling is reached
after about 990
distinct conversations and the next GWakeup allocation fails.

GLib treats a failed GWakeup as fatal, so instead of returning an error to the
caller the
whole process aborts:

  kdeconnectd[1824118]: GLib-ERROR **: Creating pipes for GWakeup: Too many
open files
  systemd-coredump: Process 1824118 (kdeconnectd) of user 1000 dumped core.
  dbus-:[email protected]: Main process exited, code=dumped,
status=5/TRAP

(this system runs a Slovak locale, so the strerror part is printed translated
in the journal.
It is shown here in the original English, EMFILE.)

Because the daemon is D-Bus activated, systemd starts a fresh instance about
two seconds
later. The client only sees org.freedesktop.DBus.Error.NoReply on the calls
that were in
flight, the user sees the phone disconnect and reconnect, and nothing points at
the cause
unless you read the journal. A liveness check does not help either, since a
different process
answers within seconds and looks perfectly healthy.

Steps to reproduce, on a phone with more than about 1000 SMS threads:

1. call requestAllConversationThreads() and wait until the phone has streamed
the thread heads
2. read activeConversations() and collect every threadID
3. call requestConversation(tid, 0, 200) for each of them

A self contained script is attached. It also has a non destructive mode that
measures the
descriptor growth without crossing the limit.

Measurements taken on the affected system:

- daemon baseline: 31 open descriptors
- 300 distinct threads requested: +300 descriptors, exactly one per thread
- the same thread requested 100 times: +0 descriptors
- descriptor type: anon_inode (eventfd), +196 for 200 distinct threads
- retention: +199 descriptors at t+20s, back to baseline at t+40s
- RLIMIT_NOFILE soft limit: 1024

Expected result:

The daemon bounds the number of conversation requests it keeps in flight, and
queues or
rejects the excess. A failed descriptor allocation is reported to the caller
rather than
aborting the process.

Actual result:

SIGTRAP, core dump, and a silent restart that hides the failure from both the
client and
the user.

Environment:

openSUSE Tumbleweed, kernel 7.2.0, Wayland session
kdeconnect-kde 26.08.0
Plasma 6.7.4, Qt 6.11.2, KF6 6.29.0, glib2 2.88.3
Phone: Volla Phone X23, 1731 SMS threads

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to