Use the same approach as in iscsi iscsi_tcp_segment_map() which makes the same operation in the same context.
In vz7 we added iov_iter_get_pages() infrastructure ourselves and we did it in safe way. We checked page before doing any manipulations on it right in core of iov_iter_get_pages() and terminated iov_iter_get_pages() if the page looked dubious. We cannot make this now because this function is used in many places over kernel and not all the places are sensitive to origin of pages but all of them definitely will crash if iov_iter_get_pages() returns error. This patch will work for now. I still believe this place deserves further investigation. It smells like mainstream could be wrong. Look at my comment in code for the reasons of doubts. Affects: #PSBM-146821, #PSBM-146846 https://jira.vzint.dev/browse/PSBM-146821 https://jira.vzint.dev/browse/PSBM-146846 Signed-off-by: Alexey Kuznetsov <kuz...@acronis.com>
From 69bd3dc09f62ec0f023d2b0a6d521e3b32ac5bd2 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov <kuz...@acronis.com> Date: Mon, 17 Apr 2023 22:07:15 +0800 Subject: fuse: pcs: do not use sendpage on pages which cannot be sendpaged Use the same approach as in iscsi iscsi_tcp_segment_map() which makes the same operation in the same context. In vz7 we added iov_iter_get_pages() infrastructure ourselves and we did it in safe way. We checked page before doing any manipulations on it right in core of iov_iter_get_pages() and terminated iov_iter_get_pages() if the page looked dubious. We cannot make this now because this function is used in many places over kernel and not all the places are sensitive to origin of pages but all of them definitely will crash if iov_iter_get_pages() returns error. This patch will work for now. I still believe this place deserves further investigation. It smells like mainstream could be wrong. Look at my comment in code for the reasons of doubts. Affects: #PSBM-146821, #PSBM-146846 https://jira.vzint.dev/browse/PSBM-146821 https://jira.vzint.dev/browse/PSBM-146846 Signed-off-by: Alexey Kuznetsov <kuz...@acronis.com> --- fs/fuse/kio/pcs/pcs_sock_io.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/fs/fuse/kio/pcs/pcs_sock_io.c b/fs/fuse/kio/pcs/pcs_sock_io.c index c43a0850dda4..c640c41f69db 100644 --- a/fs/fuse/kio/pcs/pcs_sock_io.c +++ b/fs/fuse/kio/pcs/pcs_sock_io.c @@ -151,7 +151,33 @@ static int do_send_one_seg(struct socket *sock, struct iov_iter *it, size_t left len = iov_iter_get_pages(it, &page, size, 1, &offset); BUG_ON(len <= 0); - ret = kernel_sendpage(sock, page, offset, len, flags); + /* XXX This is highly dubios place. The only thing which allows us to do + * this is ref to iscsi_tcp_segment_map() which makes the same thing in the same context. + * Good thing is that it explains in comment why slab mem cannot + * be sent to tcp: network send can coalesce neighbour slabs to single page fragment + * and this wouldbe "triggers one of hardened usercopy checks" whatever it is. + * The second condition page_count(page) >= 1 is still scary. + * AFAIK such page cannot be even handled by get_page/put_page which + * would mean that we come here with already corrupted page state. + * In vz7 we dealt with this in maybe paranoid but obviously correct way: + * iov_iter_get_pages checked sendpage_ok() _before_ making get_page and + * failing iov_iter_get_pages otherwise. I would do the same thing now, but + * I am afraid that current kernels are safe wrt get/put_page, but there is some + * other reason to prohibit page_count(page) == 0 only for networking while + * other components could be happy and would fail when we fail iov_iter_get_pages. + * Well, everyone else does not worry, so that we cab go with this. + * But still we need better justification, "everyone else" used to be stupid. + */ + if (sendpage_ok(page)) { + ret = kernel_sendpage(sock, page, offset, len, flags); + } else { + void * data = kmap(page); + struct msghdr msg = { .msg_flags = flags }; + struct kvec iov = { .iov_base = data + offset, .iov_len = len }; + + ret = kernel_sendmsg(sock, &msg, &iov, 1, len); + kunmap(page); + } put_page(page); } -- 2.38.1
_______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel