[Bug 296316] [libfetch] Fix POST upload truncation with fetchReqHTTP()

[email protected]
Newsgroups gmane.os.freebsd.bugs
Message-ID <[email protected]/bugzilla/>
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=296316

            Bug ID: 296316
           Summary: [libfetch] Fix POST upload truncation with
                    fetchReqHTTP()
           Product: Base System
           Version: 15.1-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: bin
          Assignee: [email protected]
          Reporter: [email protected]

Created attachment 272175
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=272175&action=edit
Fix for the described problem

I noticed a regression in 15.1 that causes fetchReqHTTP() to get stuck when
uploading a file via HTTPS POST request. It worked fine with FreeBSD 15.0. A
small utility that I use was able to trigger that very reliable:

https://codeberg.org/decke/mrpt-upload/src/branch/main/mrpt-upload.c

I used Claude to analyze the truss output and generate a patch that works for
me:


fetch_writev() in lib/libfetch/common.c uses a non-blocking socket with
a poll-and-write loop. The inner poll loop is gated on pfd.revents == 0,
but pfd.revents is never reset after a successful write. On subsequent
iterations the poll is skipped and SSL_write() is called immediately
without checking socket readiness. When the send buffer is full and
SSL_write() returns -1 with errno == EAGAIN, the error is not retried
— the function returns -1, silently truncating the request body.

For unencrypted connections this is less likely to trigger because
writev() operates on all iovec entries at once. For SSL, SSL_write()
operates on a single iovec per call, making short writes and a
subsequent EAGAIN much more likely with large request bodies.

The result observed with fetchReqHTTP() over HTTPS is that the server
receives a truncated POST body, returns an error response, closes its
end of the connection, and fetch_writev() then hangs polling for a
response that never arrives — until fetchTimeout fires.

Fix: In the wlen < 0 branch of fetch_writev(), handle EAGAIN by
resetting pfd.revents = 0 and continuing the loop, re-engaging the poll
before retrying SSL_write().

-- 
You are receiving this mail because:
You are the assignee for the bug.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.