From: Greg Kroah-Hartman Date: Tue, 4 Oct 2022 17:47:01 +0000 (+0200) Subject: drop don-t-use-__kernel_write-on-kmap_local_page.patch from everywhere X-Git-Tag: v4.19.261~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d6347f71f71285e7ceb43dd455ed54578e9085c1;p=thirdparty%2Fkernel%2Fstable-queue.git drop don-t-use-__kernel_write-on-kmap_local_page.patch from everywhere --- diff --git a/queue-5.15/don-t-use-__kernel_write-on-kmap_local_page.patch b/queue-5.15/don-t-use-__kernel_write-on-kmap_local_page.patch deleted file mode 100644 index 5b91999e598..00000000000 --- a/queue-5.15/don-t-use-__kernel_write-on-kmap_local_page.patch +++ /dev/null @@ -1,160 +0,0 @@ -From a5a9fb5fa149036b2f1ef580c2427512b0856e9d Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 26 Sep 2022 11:59:14 -0400 -Subject: don't use __kernel_write() on kmap_local_page() - -From: Al Viro - -[ Upstream commit 06bbaa6dc53cb72040db952053432541acb9adc7 ] - -passing kmap_local_page() result to __kernel_write() is unsafe - -random ->write_iter() might (and 9p one does) get unhappy when -passed ITER_KVEC with pointer that came from kmap_local_page(). - -Fix by providing a variant of __kernel_write() that takes an iov_iter -from caller (__kernel_write() becomes a trivial wrapper) and adding -dump_emit_page() that parallels dump_emit(), except that instead of -__kernel_write() it uses __kernel_write_iter() with ITER_BVEC source. - -Fixes: 3159ed57792b "fs/coredump: use kmap_local_page()" -Signed-off-by: Al Viro -Signed-off-by: Sasha Levin ---- - fs/coredump.c | 38 +++++++++++++++++++++++++++++++++----- - fs/internal.h | 3 +++ - fs/read_write.c | 22 ++++++++++++++-------- - 3 files changed, 50 insertions(+), 13 deletions(-) - -diff --git a/fs/coredump.c b/fs/coredump.c -index 26eb5a095832..43fdd82f82ab 100644 ---- a/fs/coredump.c -+++ b/fs/coredump.c -@@ -902,6 +902,38 @@ static int __dump_skip(struct coredump_params *cprm, size_t nr) - } - } - -+static int dump_emit_page(struct coredump_params *cprm, struct page *page) -+{ -+ struct bio_vec bvec = { -+ .bv_page = page, -+ .bv_offset = 0, -+ .bv_len = PAGE_SIZE, -+ }; -+ struct iov_iter iter; -+ struct file *file = cprm->file; -+ loff_t pos = file->f_pos; -+ ssize_t n; -+ -+ if (cprm->to_skip) { -+ if (!__dump_skip(cprm, cprm->to_skip)) -+ return 0; -+ cprm->to_skip = 0; -+ } -+ if (cprm->written + PAGE_SIZE > cprm->limit) -+ return 0; -+ if (dump_interrupted()) -+ return 0; -+ iov_iter_bvec(&iter, WRITE, &bvec, 1, PAGE_SIZE); -+ n = __kernel_write_iter(cprm->file, &iter, &pos); -+ if (n != PAGE_SIZE) -+ return 0; -+ file->f_pos = pos; -+ cprm->written += PAGE_SIZE; -+ cprm->pos += PAGE_SIZE; -+ -+ return 1; -+} -+ - int dump_emit(struct coredump_params *cprm, const void *addr, int nr) - { - if (cprm->to_skip) { -@@ -933,7 +965,6 @@ int dump_user_range(struct coredump_params *cprm, unsigned long start, - - for (addr = start; addr < start + len; addr += PAGE_SIZE) { - struct page *page; -- int stop; - - /* - * To avoid having to allocate page tables for virtual address -@@ -944,10 +975,7 @@ int dump_user_range(struct coredump_params *cprm, unsigned long start, - */ - page = get_dump_page(addr); - if (page) { -- void *kaddr = kmap_local_page(page); -- -- stop = !dump_emit(cprm, kaddr, PAGE_SIZE); -- kunmap_local(kaddr); -+ int stop = !dump_emit_page(cprm, page); - put_page(page); - if (stop) - return 0; -diff --git a/fs/internal.h b/fs/internal.h -index 4f1fe6d08866..69b64136ae4c 100644 ---- a/fs/internal.h -+++ b/fs/internal.h -@@ -16,6 +16,7 @@ struct shrink_control; - struct fs_context; - struct user_namespace; - struct pipe_inode_info; -+struct iov_iter; - - /* - * block/bdev.c -@@ -219,3 +220,5 @@ struct xattr_ctx { - int setxattr_copy(const char __user *name, struct xattr_ctx *ctx); - int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry, - struct xattr_ctx *ctx); -+ -+ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *pos); -diff --git a/fs/read_write.c b/fs/read_write.c -index 8d3ec975514d..08299a8f3e05 100644 ---- a/fs/read_write.c -+++ b/fs/read_write.c -@@ -512,14 +512,9 @@ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t - } - - /* caller is responsible for file_start_write/file_end_write */ --ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) -+ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *pos) - { -- struct kvec iov = { -- .iov_base = (void *)buf, -- .iov_len = min_t(size_t, count, MAX_RW_COUNT), -- }; - struct kiocb kiocb; -- struct iov_iter iter; - ssize_t ret; - - if (WARN_ON_ONCE(!(file->f_mode & FMODE_WRITE))) -@@ -535,8 +530,7 @@ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t - - init_sync_kiocb(&kiocb, file); - kiocb.ki_pos = pos ? *pos : 0; -- iov_iter_kvec(&iter, WRITE, &iov, 1, iov.iov_len); -- ret = file->f_op->write_iter(&kiocb, &iter); -+ ret = file->f_op->write_iter(&kiocb, from); - if (ret > 0) { - if (pos) - *pos = kiocb.ki_pos; -@@ -546,6 +540,18 @@ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t - inc_syscw(current); - return ret; - } -+ -+/* caller is responsible for file_start_write/file_end_write */ -+ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) -+{ -+ struct kvec iov = { -+ .iov_base = (void *)buf, -+ .iov_len = min_t(size_t, count, MAX_RW_COUNT), -+ }; -+ struct iov_iter iter; -+ iov_iter_kvec(&iter, WRITE, &iov, 1, iov.iov_len); -+ return __kernel_write_iter(file, &iter, pos); -+} - /* - * This "EXPORT_SYMBOL_GPL()" is more of a "EXPORT_SYMBOL_DONTUSE()", - * but autofs is one of the few internal kernel users that actually --- -2.35.1 - diff --git a/queue-5.15/series b/queue-5.15/series index 98e9029a4b8..7df3ddae231 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -64,7 +64,6 @@ net-phy-don-t-warn-for-phy_up-state-in-mdio_bus_phy_.patch selftests-fix-the-if-conditions-of-in-test_extra_fil.patch vdpa-ifcvf-fix-the-calculation-of-queuepair.patch fs-split-off-setxattr_copy-and-do_setxattr-function-.patch -don-t-use-__kernel_write-on-kmap_local_page.patch clk-imx-imx6sx-remove-the-set_rate_parent-flag-for-q.patch clk-iproc-do-not-rely-on-node-name-for-correct-pll-s.patch kvm-x86-hide-ia32_platform_dca_cap-31-0-from-the-gue.patch diff --git a/queue-5.19/don-t-use-__kernel_write-on-kmap_local_page.patch b/queue-5.19/don-t-use-__kernel_write-on-kmap_local_page.patch deleted file mode 100644 index 43ad2e6c475..00000000000 --- a/queue-5.19/don-t-use-__kernel_write-on-kmap_local_page.patch +++ /dev/null @@ -1,160 +0,0 @@ -From bbb6fad0e391971325367d5ceb857b80f754c626 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 26 Sep 2022 11:59:14 -0400 -Subject: don't use __kernel_write() on kmap_local_page() - -From: Al Viro - -[ Upstream commit 06bbaa6dc53cb72040db952053432541acb9adc7 ] - -passing kmap_local_page() result to __kernel_write() is unsafe - -random ->write_iter() might (and 9p one does) get unhappy when -passed ITER_KVEC with pointer that came from kmap_local_page(). - -Fix by providing a variant of __kernel_write() that takes an iov_iter -from caller (__kernel_write() becomes a trivial wrapper) and adding -dump_emit_page() that parallels dump_emit(), except that instead of -__kernel_write() it uses __kernel_write_iter() with ITER_BVEC source. - -Fixes: 3159ed57792b "fs/coredump: use kmap_local_page()" -Signed-off-by: Al Viro -Signed-off-by: Sasha Levin ---- - fs/coredump.c | 38 +++++++++++++++++++++++++++++++++----- - fs/internal.h | 3 +++ - fs/read_write.c | 22 ++++++++++++++-------- - 3 files changed, 50 insertions(+), 13 deletions(-) - -diff --git a/fs/coredump.c b/fs/coredump.c -index ebc43f960b64..f1355e52614a 100644 ---- a/fs/coredump.c -+++ b/fs/coredump.c -@@ -832,6 +832,38 @@ static int __dump_skip(struct coredump_params *cprm, size_t nr) - } - } - -+static int dump_emit_page(struct coredump_params *cprm, struct page *page) -+{ -+ struct bio_vec bvec = { -+ .bv_page = page, -+ .bv_offset = 0, -+ .bv_len = PAGE_SIZE, -+ }; -+ struct iov_iter iter; -+ struct file *file = cprm->file; -+ loff_t pos = file->f_pos; -+ ssize_t n; -+ -+ if (cprm->to_skip) { -+ if (!__dump_skip(cprm, cprm->to_skip)) -+ return 0; -+ cprm->to_skip = 0; -+ } -+ if (cprm->written + PAGE_SIZE > cprm->limit) -+ return 0; -+ if (dump_interrupted()) -+ return 0; -+ iov_iter_bvec(&iter, WRITE, &bvec, 1, PAGE_SIZE); -+ n = __kernel_write_iter(cprm->file, &iter, &pos); -+ if (n != PAGE_SIZE) -+ return 0; -+ file->f_pos = pos; -+ cprm->written += PAGE_SIZE; -+ cprm->pos += PAGE_SIZE; -+ -+ return 1; -+} -+ - int dump_emit(struct coredump_params *cprm, const void *addr, int nr) - { - if (cprm->to_skip) { -@@ -863,7 +895,6 @@ int dump_user_range(struct coredump_params *cprm, unsigned long start, - - for (addr = start; addr < start + len; addr += PAGE_SIZE) { - struct page *page; -- int stop; - - /* - * To avoid having to allocate page tables for virtual address -@@ -874,10 +905,7 @@ int dump_user_range(struct coredump_params *cprm, unsigned long start, - */ - page = get_dump_page(addr); - if (page) { -- void *kaddr = kmap_local_page(page); -- -- stop = !dump_emit(cprm, kaddr, PAGE_SIZE); -- kunmap_local(kaddr); -+ int stop = !dump_emit_page(cprm, page); - put_page(page); - if (stop) - return 0; -diff --git a/fs/internal.h b/fs/internal.h -index 87e96b9024ce..3e206d3e317c 100644 ---- a/fs/internal.h -+++ b/fs/internal.h -@@ -16,6 +16,7 @@ struct shrink_control; - struct fs_context; - struct user_namespace; - struct pipe_inode_info; -+struct iov_iter; - - /* - * block/bdev.c -@@ -221,3 +222,5 @@ ssize_t do_getxattr(struct user_namespace *mnt_userns, - int setxattr_copy(const char __user *name, struct xattr_ctx *ctx); - int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry, - struct xattr_ctx *ctx); -+ -+ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *pos); -diff --git a/fs/read_write.c b/fs/read_write.c -index 397da0236607..a0a3d35e2c0f 100644 ---- a/fs/read_write.c -+++ b/fs/read_write.c -@@ -509,14 +509,9 @@ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t - } - - /* caller is responsible for file_start_write/file_end_write */ --ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) -+ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *pos) - { -- struct kvec iov = { -- .iov_base = (void *)buf, -- .iov_len = min_t(size_t, count, MAX_RW_COUNT), -- }; - struct kiocb kiocb; -- struct iov_iter iter; - ssize_t ret; - - if (WARN_ON_ONCE(!(file->f_mode & FMODE_WRITE))) -@@ -532,8 +527,7 @@ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t - - init_sync_kiocb(&kiocb, file); - kiocb.ki_pos = pos ? *pos : 0; -- iov_iter_kvec(&iter, WRITE, &iov, 1, iov.iov_len); -- ret = file->f_op->write_iter(&kiocb, &iter); -+ ret = file->f_op->write_iter(&kiocb, from); - if (ret > 0) { - if (pos) - *pos = kiocb.ki_pos; -@@ -543,6 +537,18 @@ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t - inc_syscw(current); - return ret; - } -+ -+/* caller is responsible for file_start_write/file_end_write */ -+ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) -+{ -+ struct kvec iov = { -+ .iov_base = (void *)buf, -+ .iov_len = min_t(size_t, count, MAX_RW_COUNT), -+ }; -+ struct iov_iter iter; -+ iov_iter_kvec(&iter, WRITE, &iov, 1, iov.iov_len); -+ return __kernel_write_iter(file, &iter, pos); -+} - /* - * This "EXPORT_SYMBOL_GPL()" is more of a "EXPORT_SYMBOL_DONTUSE()", - * but autofs is one of the few internal kernel users that actually --- -2.35.1 - diff --git a/queue-5.19/series b/queue-5.19/series index 39947589330..21814af315b 100644 --- a/queue-5.19/series +++ b/queue-5.19/series @@ -86,7 +86,6 @@ ice-xsk-drop-power-of-2-ring-size-restriction-for-af.patch vdpa-ifcvf-fix-the-calculation-of-queuepair.patch virtio-blk-fix-warn_on_once-in-virtio_queue_rq.patch vdpa-mlx5-fix-mq-to-support-non-power-of-two-num-que.patch -don-t-use-__kernel_write-on-kmap_local_page.patch clk-imx-imx6sx-remove-the-set_rate_parent-flag-for-q.patch drm-i915-gt-perf_limit_reasons-are-only-available-fo.patch clk-iproc-do-not-rely-on-node-name-for-correct-pll-s.patch