linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* sendfile(2) erroneously yields EINVAL on too large counts
@ 2024-02-15 13:49 Jan Engelhardt
  2024-03-04 13:52 ` Alejandro Colomar
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Engelhardt @ 2024-02-15 13:49 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: linux-man, Al Viro


Observed:
The following program below leads to sendfile returning -1 and setting 
errno=EINVAL.

Expected:
Return 0.

System: Linux 6.7.4 amd64 glibc-2.39

Rationale:

As per man-pages 6.60's sendfile.2 page:

       EINVAL Descriptor is not valid or locked, or an mmap(2)-like 
              operation is not available for in_fd, or count is 
              negative.

(Invalid descriptors should yield EBADF instead, I think.)
mmap is probably functional, since the testcase works if write() calls 
are removed.
count is not negative.

It appears that there may be a `src offset + count > SSIZE_MAX || dst offset +
count > SSIZE_MAX` check in the kernel somewhere, which sounds an awful lot
like the documented EOVERFLOW behavior:

       EOVERFLOW
              count is too large, the operation would result in exceeding the maximum size of ei‐
              ther the input file or the output file.

but the reported error is EINVAL rather than EOVERFLOW. Moreover, the (actual) result
from this testcase does not go above a few bytes anyhow, so should not signal
an overflow anyway.

#define _GNU_SOURCE 1
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/sendfile.h>
int main(int argc, char **argv)
{
        int src = open(".", O_RDWR | O_TMPFILE, 0666);
        write(src, "1234", 4);
        int dst = open(".", O_RDWR | O_TMPFILE, 0666);
        write(src, "1234", 4);
        ssize_t ret = sendfile(dst, src, NULL, SSIZE_MAX);
        printf("%ld\n", (long)ret);
        if (ret < 0)
                printf("%s\n", strerror(errno));
        return 0;
}

As it stands, a sendfile() user just wanting to shovel src to dst
cannot just "fire-and-forget" but has to compute a suitable count 
beforehand.
Is this really what we want?

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-03-10 18:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-15 13:49 sendfile(2) erroneously yields EINVAL on too large counts Jan Engelhardt
2024-03-04 13:52 ` Alejandro Colomar
2024-03-04 15:09   ` Undefined Behavior in rw_verify_area() (was: sendfile(2) erroneously yields EINVAL on too large counts) Alejandro Colomar
2024-03-04 15:22     ` Matthew Wilcox
2024-03-04 15:31       ` Alejandro Colomar
2024-03-10 18:35   ` sendfile(2) erroneously yields EINVAL on too large counts Jan Engelhardt
2024-03-10 18:53     ` Alejandro Colomar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).