linux-loongson/drivers/infiniband/sw/siw
Pedro Falcato c18646248f RDMA/siw: Fix the sendmsg byte count in siw_tcp_sendpages
Ever since commit c2ff29e99a ("siw: Inline do_tcp_sendpages()"),
we have been doing this:

static int siw_tcp_sendpages(struct socket *s, struct page **page, int offset,
                             size_t size)
[...]
        /* Calculate the number of bytes we need to push, for this page
         * specifically */
        size_t bytes = min_t(size_t, PAGE_SIZE - offset, size);
        /* If we can't splice it, then copy it in, as normal */
        if (!sendpage_ok(page[i]))
                msg.msg_flags &= ~MSG_SPLICE_PAGES;
        /* Set the bvec pointing to the page, with len $bytes */
        bvec_set_page(&bvec, page[i], bytes, offset);
        /* Set the iter to $size, aka the size of the whole sendpages (!!!) */
        iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size);
try_page_again:
        lock_sock(sk);
        /* Sendmsg with $size size (!!!) */
        rv = tcp_sendmsg_locked(sk, &msg, size);

This means we've been sending oversized iov_iters and tcp_sendmsg calls
for a while. This has a been a benign bug because sendpage_ok() always
returned true. With the recent slab allocator changes being slowly
introduced into next (that disallow sendpage on large kmalloc
allocations), we have recently hit out-of-bounds crashes, due to slight
differences in iov_iter behavior between the MSG_SPLICE_PAGES and
"regular" copy paths:

(MSG_SPLICE_PAGES)
skb_splice_from_iter
  iov_iter_extract_pages
    iov_iter_extract_bvec_pages
      uses i->nr_segs to correctly stop in its tracks before OoB'ing everywhere
  skb_splice_from_iter gets a "short" read

(!MSG_SPLICE_PAGES)
skb_copy_to_page_nocache copy=iov_iter_count
 [...]
   copy_from_iter
        /* this doesn't help */
        if (unlikely(iter->count < len))
                len = iter->count;
          iterate_bvec
            ... and we run off the bvecs

Fix this by properly setting the iov_iter's byte count, plus sending the
correct byte count to tcp_sendmsg_locked.

Link: https://patch.msgid.link/r/20250729120348.495568-1-pfalcato@suse.de
Cc: stable@vger.kernel.org
Fixes: c2ff29e99a ("siw: Inline do_tcp_sendpages()")
Reported-by: kernel test robot <oliver.sang@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202507220801.50a7210-lkp@intel.com
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Pedro Falcato <pfalcato@suse.de>
Acked-by: Bernard Metzler <bernard.metzler@linux.dev>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
2025-08-05 11:33:10 -03:00
..
iwarp.h IB: Use capital "OR" for multiple licenses in SPDX 2023-09-11 14:14:00 +03:00
Kconfig RDMA/siw: use skb_crc32c() instead of __skb_checksum() 2025-05-21 15:40:05 -07:00
Makefile
siw_cm.c RDMA/siw: Remove direct link to net_device 2024-12-19 05:18:37 -05:00
siw_cm.h IB: Use capital "OR" for multiple licenses in SPDX 2023-09-11 14:14:00 +03:00
siw_cq.c RDMA: Don't use %pK through printk 2025-04-09 14:30:10 -04:00
siw_main.c RDMA/siw: Switch to using the crc32c library 2025-03-03 07:14:33 -05:00
siw_mem.c RDMA/siw: Remove unused siw_mem_add 2025-05-06 14:30:13 -03:00
siw_mem.h RDMA/siw: Remove unused siw_mem_add 2025-05-06 14:30:13 -03:00
siw_qp_rx.c RDMA: Don't use %pK through printk 2025-04-09 14:30:10 -04:00
siw_qp_tx.c RDMA/siw: Fix the sendmsg byte count in siw_tcp_sendpages 2025-08-05 11:33:10 -03:00
siw_qp.c RDMA/siw: Switch to using the crc32c library 2025-03-03 07:14:33 -05:00
siw_verbs.c IB: Extend UVERBS_METHOD_REG_MR to get DMAH 2025-07-23 01:42:11 -04:00
siw_verbs.h IB: Extend UVERBS_METHOD_REG_MR to get DMAH 2025-07-23 01:42:11 -04:00
siw.h RDMA v6.16 merge window pull request 2025-05-30 10:18:56 -07:00