[PATCH OLK-5.10 0/2] arm64: exec: add mcs support for prepare_binprm

Add machine check safe support for prepare_binprm. Wupeng Ma (2): iov_iter: add copy_mc_page_to_kvec_iter arm64: exec: add mcs support for prepare_binprm fs/exec.c | 16 +++++++++++++++- include/linux/uio.h | 2 ++ lib/iov_iter.c | 18 ++++++++++++++++++ mm/shmem.c | 10 +++++++++- 4 files changed, 44 insertions(+), 2 deletions(-) -- 2.43.0

hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/ICLL1L -------------------------------- Add copy_mc_page_to_kvec_iter for ITER_KVEC to support machine safe. Signed-off-by: Wupeng Ma <mawupeng1@huawei.com> --- include/linux/uio.h | 2 ++ lib/iov_iter.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/linux/uio.h b/include/linux/uio.h index cedb68e49e4f..1bf0a426ef02 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -141,6 +141,8 @@ size_t _copy_from_iter(void *addr, size_t bytes, struct iov_iter *i); bool _copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i); size_t _copy_from_iter_nocache(void *addr, size_t bytes, struct iov_iter *i); bool _copy_from_iter_full_nocache(void *addr, size_t bytes, struct iov_iter *i); +size_t copy_mc_page_to_kvec_iter(struct page *page, size_t offset, size_t bytes, + struct iov_iter *i); static __always_inline __must_check size_t copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i) diff --git a/lib/iov_iter.c b/lib/iov_iter.c index ce8c225237f5..15b373f2e508 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -908,6 +908,24 @@ static inline bool page_copy_sane(struct page *page, size_t offset, size_t n) return false; } +size_t copy_mc_page_to_kvec_iter(struct page *page, size_t offset, size_t bytes, + struct iov_iter *i) +{ + size_t wanted; + void *kaddr; + + if (unlikely(!page_copy_sane(page, offset, bytes))) + return 0; + + if (!(i->type & ITER_KVEC)) + return 0; + + kaddr = kmap_atomic(page); + wanted = copy_mc_to_iter(kaddr + offset, bytes, i); + kunmap_atomic(kaddr); + return wanted; +} + size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, struct iov_iter *i) { -- 2.43.0

hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/ICLL1L -------------------------------- During out test, system will panic during prepare_binprm if the binary data is in tmpfs and is corrupt as follow: Internal error: synchronous external abort: ffffffff96000410 [#1] SMP CPU: 468 PID: 15075 Comm: bash Kdump: loaded Not tainted 5.10.0+ #8 Call trace: __memcpy+0x100/0x180 copy_page_to_iter+0x150/0x210 shmem_file_read_iter+0x1f8/0x464 __kernel_read+0x100/0x2bc kernel_read+0x60/0x90 search_binary_handler+0x5c/0x354 exec_binprm+0x5c/0x1dc bprm_execve.part.0+0xa0/0x130 bprm_execve+0x58/0xa0 do_execveat_common+0x1b0/0x230 __arm64_sys_execve+0x48/0x70 invoke_syscall+0x50/0x134 el0_svc_common.constprop.0+0x10c/0x124 do_el0_svc+0x34/0xe0 el0_svc+0x20/0x30 el0_sync_handler+0xb8/0xc0 fast_work_pending464+0x178/0x190 Code: d503201f d503201f d503201f d503201f (a8c12027) SMP: stopping secondary CPUs To fix this, add machine check safe support for bprm_execve if binrpm is read by shmem_file_read_iter. Signed-off-by: Wupeng Ma <mawupeng1@huawei.com> --- fs/exec.c | 16 +++++++++++++++- mm/shmem.c | 10 +++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 371f96c3d5b8..17e11c9bfa30 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1685,10 +1685,24 @@ static int bprm_creds_from_file(struct linux_binprm *bprm) */ static int prepare_binprm(struct linux_binprm *bprm) { + unsigned int flags = 0; loff_t pos = 0; + int ret; + + /* + * Update task flag with PF_MCS to enable mcs support during + * reading binrpm + */ + if (IS_ENABLED(CONFIG_ARM64) && IS_ENABLED(CONFIG_ARCH_HAS_COPY_MC) && + !(current->flags & PF_MCS)) + flags = PF_MCS; + current->flags |= flags; memset(bprm->buf, 0, BINPRM_BUF_SIZE); - return kernel_read(bprm->file, bprm->buf, BINPRM_BUF_SIZE, &pos); + ret = kernel_read(bprm->file, bprm->buf, BINPRM_BUF_SIZE, &pos); + current->flags &= ~flags; + + return ret; } /* diff --git a/mm/shmem.c b/mm/shmem.c index 9cb612d1153b..a5e7ed01943b 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2601,10 +2601,15 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to) int error = 0; ssize_t retval = 0; loff_t *ppos = &iocb->ki_pos; + bool use_copy_mc = false; index = *ppos >> PAGE_SHIFT; offset = *ppos & ~PAGE_MASK; + if (IS_ENABLED(CONFIG_ARM64) && IS_ENABLED(CONFIG_ARCH_HAS_COPY_MC) && + (current->flags & PF_MCS) && iov_iter_is_kvec(to)) + use_copy_mc = true; + for (;;) { struct page *page = NULL; pgoff_t end_index; @@ -2664,7 +2669,10 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to) * Ok, we have the page, and it's up-to-date, so * now we can copy it to user space... */ - ret = copy_page_to_iter(page, offset, nr, to); + if (use_copy_mc) + ret = copy_mc_page_to_kvec_iter(page, offset, nr, to); + else + ret = copy_page_to_iter(page, offset, nr, to); put_page(page); } else if (iter_is_iovec(to)) { -- 2.43.0

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/17099 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/CN7... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/17099 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/CN7...
participants (2)
-
patchwork bot
-
Wupeng Ma