Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-141419

QNetworkAccessManager high CPU usage if outgoing packet is rejected by nftables

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P1: Critical P1: Critical
    • None
    • 5.15.19, 6.10.0
    • Network: HTTP
    • Debian 12 amd64
    • Linux/X11

      If we block outgoing packets with reject (to test how application handles rejects/drops) like this:

      nft add rule inet filter output ip daddr 192.168.1.123 counter reject

      Application starts to "flood" connect and poll syscalls, producing high (up to 100%) CPU load:

       

      strace: Process 835162 attached
      [pid 835160] 16:27:40.674183 poll([{fd=3, events=POLLIN}], 1, 0) = 1 ([{fd=3, revents=POLLIN}])
      [pid 835160] 16:27:40.674241 poll([{fd=3, events=POLLIN}], 1, 1003 <unfinished ...>
      [pid 835162] 16:27:40.674274 poll([{fd=4, events=POLLIN}], 1, 0) = 0 (Timeout)
      [pid 835162] 16:27:40.674335 poll([{fd=4, events=POLLIN}], 1, 0) = 1 ([{fd=4, revents=POLLIN}])
      [pid 835162] 16:27:40.674409 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EINPROGRESS (Operation now in progress)
      [pid 835162] 16:27:40.674516 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 0) = 2 ([{fd=4, revents=POLLIN}, {fd=5, revents=POLLERR}])
      [pid 835160] 16:27:40.674547 <... poll resumed>) = 1 ([{fd=3, revents=POLLIN}])
      [pid 835162] 16:27:40.674551 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)
      [pid 835160] 16:27:40.674565 poll([{fd=3, events=POLLIN}], 1, 1002 <unfinished ...>
      [pid 835162] 16:27:40.674569 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 30002) = 1 ([{fd=5, revents=POLLERR}])
      [pid 835162] 16:27:40.674581 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)
      [pid 835162] 16:27:40.674594 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 30002) = 1 ([{fd=5, revents=POLLERR}])
      [pid 835162] 16:27:40.674606 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)
      [pid 835162] 16:27:40.674618 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 30002) = 1 ([{fd=5, revents=POLLERR}])
      [pid 835162] 16:27:40.674630 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)
      [pid 835162] 16:27:40.674642 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 30002) = 1 ([{fd=5, revents=POLLERR}])
      [pid 835162] 16:27:40.674654 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)
      [pid 835162] 16:27:40.674666 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 30002) = 1 ([{fd=5, revents=POLLERR}])
      [pid 835162] 16:27:40.674678 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)
      [pid 835162] 16:27:40.674690 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 30002) = 1 ([{fd=5, revents=POLLERR}])
      [pid 835162] 16:27:40.674702 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)
      [pid 835162] 16:27:40.674715 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 30002) = 1 ([{fd=5, revents=POLLERR}])
      [pid 835162] 16:27:40.674727 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)
      [pid 835162] 16:27:40.674739 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 30002) = 1 ([{fd=5, revents=POLLERR}])
      [pid 835162] 16:27:40.674751 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)
      [pid 835162] 16:27:40.674763 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 30002) = 1 ([{fd=5, revents=POLLERR}])
      [pid 835162] 16:27:40.674775 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)
      [pid 835162] 16:27:40.674787 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 30002) = 1 ([{fd=5, revents=POLLERR}])
      [pid 835162] 16:27:40.674800 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)
      [pid 835162] 16:27:40.674812 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 30002) = 1 ([{fd=5, revents=POLLERR}])
      [pid 835162] 16:27:40.674824 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)
      [pid 835162] 16:27:40.674837 poll([{fd=4, events=POLLIN}, {fd=5, events=POLLOUT}], 2, 30002) = 1 ([{fd=5, revents=POLLERR}])
      [pid 835162] 16:27:40.674849 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.123")}, 16) = -1 EALREADY (Operation already in progress)

      Then, if we change rule to drop, instead of reject:

      nft replace rule inet filter output handle $HANDLE ip daddr 192.168.1.123 counter drop 

      And then we launch application, it behaves nicely (no CPU load). We then can replaced back to reject while test application is running and again see CPU load.

      Later, if we change IP address to some existing network device like router 192.168.1.1 (which does not service port 80) without matching firewall rules, we will get "Connection refused" but without CPU load.

      So I guess problem is when the system itself produces "fast-track reject", and Qt handles it in some problematic way, producing "endless" loop of sorts.

      Will attach reproduction shortly.

       

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            manordheim Mårten Nordheim
            talkless Vincas Dargis
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:

                There are no open Gerrit changes