Menu ▾ ▴

#2777 sblim-sfcc: indicationlistener: readData() loops forever when the peer closes mid-body

Code_Cleanup
open
nobody
None
sfcc
5
2026-09-25
2026-09-25
No

Affects 2.2.8 (current release).

readData() in backend/cimxml/indicationlistener.c loops until it has read the
full requested count, but never leaves the loop when the peer stops sending:

while (c < length) {
    r = commRead(conn_fd, into + c, length - c);
    if (r < 0 && (errno == EINTR || errno == EAGAIN)) {
        continue;
    }
    c += r;
}

commRead() wraps read(2), so it returns 0 at EOF and -1 on error. Neither is
handled. On EOF c never advances and the loop spins at 100% CPU. On a fatal
error c is decremented once per read() and runs away until it wraps from
INT_MIN to INT_MAX, at which point readData() returns a bogus 2147483647.

getPayload() calls readData() with the client-supplied Content-Length, and
establish_listener() calls handleConnection() inline in a single-threaded
accept loop. So any request whose body is shorter than its Content-Length
header wedges the listener permanently - it never returns to accept() and
delivers no further indication for the life of the process.

No malicious peer is needed. Any connection dropped mid-body - CIMOM restart,
network partition, firewall idle timeout, RST - is enough.

Reproducer: start an indication listener, connect, send

POST /indication HTTP/1.1
Host: localhost
Content-Length: 200
Expect: 100-continue

with no body, then shutdown(fd, SHUT_WR). The listener stops answering.

Patch attached (against pristine 2.2.8). It breaks out of the loop on EOF and
on fatal read errors, and updates getPayload() to terminate the payload after
what was actually received rather than at content_length - otherwise a short
read leaves uninitialized heap from the malloc() inside the string handed to
the CIM-XML parser.

1 Attachments

Discussion


Log in to post a comment.