[Bug 282495] Linuxulator sendfile returns EGAIN repeatedly, actually repeatingly sending data

From: <bugzilla-noreply_at_freebsd.org>
Date: Sat, 02 Nov 2024 16:27:07 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=282495

            Bug ID: 282495
           Summary: Linuxulator sendfile returns EGAIN repeatedly,
                    actually repeatingly sending data
           Product: Base System
           Version: 14.1-RELEASE
          Hardware: amd64
                OS: Any
            Status: New
          Severity: Affects Many People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: pieter@krikkit.xyz

Created attachment 254879
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=254879&action=edit
Simple Go executable that shows an adapted internal Go sendfile wrapper
exercising the apparent bug

I'm not currently able to dive deeper, but running a very basic Go HTTP
webserver in the Linuxulator on 14.1-RELEASE-p5 gave me corrupted downloads.  I
dove into the standard Go libraries and found that ultimately, sendfile is used
for such data transfers.

My test code is a simplified version of the Go code that shows the main issue:
the linux_sendfile syscall returns EAGAIN as errno and -1 as result, BUT
there's actually data being sent. This is only the case when the TCP socket is
marked as non-blocking. At EAGAIN the Go library code retries until success,
which in practice means that much more data is sent than expected and pieces of
data are repeated. Every time I execute the test, the output is different.

My attached test code exercises this:
% go build main.go
% ./main & 
% nc -v localhost 4040 > testfile

I'm stopping the loop at EAGAIN directly, but normally it would retry a number
of times, every time a bit of data actually being sent, but the sender not
knowing about it. 

The Linux sendfile man page indicates that sendfile can return early without
having sent all data, but this isn't an error.  So either linux_sendfile should
return the amount of bytes sent and no error, OR not actually send any data and
return EAGAIN and -1.

-- 
You are receiving this mail because:
You are the assignee for the bug.