From patchwork Tue Jul 11 07:40:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiubo Li X-Patchwork-Id: 9834221 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2819860325 for ; Tue, 11 Jul 2017 08:02:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1EF442041F for ; Tue, 11 Jul 2017 08:02:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 135C8283C7; Tue, 11 Jul 2017 08:02:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2CA0E2041F for ; Tue, 11 Jul 2017 08:02:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755396AbdGKICu (ORCPT ); Tue, 11 Jul 2017 04:02:50 -0400 Received: from cmccmta1.chinamobile.com ([221.176.66.79]:57419 "EHLO cmccmta1.chinamobile.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755355AbdGKICq (ORCPT ); Tue, 11 Jul 2017 04:02:46 -0400 Received: from spf.mail.chinamobile.com (unknown[172.16.121.11]) by rmmx-syy-dmz-app01-12001 (RichMail) with SMTP id 2ee159648621f2c-561ac; Tue, 11 Jul 2017 16:02:41 +0800 (CST) X-RM-TRANSID: 2ee159648621f2c-561ac X-RM-SPAM-FLAG: 00000000 Received: from localhost.localdomain (unknown[223.105.0.130]) by rmsmtp-syy-appsvr06-12006 (RichMail) with SMTP id 2ee659648620b64-1e29a; Tue, 11 Jul 2017 16:02:41 +0800 (CST) X-RM-TRANSID: 2ee659648620b64-1e29a From: lixiubo@cmss.chinamobile.com To: nab@linux-iscsi.org, mchristi@redhat.com Cc: bryantly@linux.vnet.ibm.com, linux-scsi@vger.kernel.org, target-devel@vger.kernel.org, Xiubo Li Subject: [PATCH] tcmu: Fix possible overflow for memcpy address in iovec Date: Tue, 11 Jul 2017 15:40:43 +0800 Message-Id: <1499758843-14159-1-git-send-email-lixiubo@cmss.chinamobile.com> X-Mailer: git-send-email 1.8.3.1 Sender: target-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: target-devel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Xiubo Li Before the data area dynamic grow patches, though the overflow bug was already exist, since the data area memories are all preallocated, so there mostly won't any bad page fault core trace produced. The dynamic grow patches will only allocate and map the block needed in data area, so when memcpy overflow, the system will die. [ 367.864705] [c0000000fc657340] [c0000000000d220c] do_exit+0x79c/0xcf0 [ 367.864710] [c0000000fc657410] [c0000000000249a4] die+0x314/0x470 [ 367.864715] [c0000000fc6574a0] [c00000000005425c] bad_page_fault+0xdc/0x150 [ 367.864720] [c0000000fc657510] [c000000000008964] handle_page_fault+0x2c/0x30 [ 367.864726] --- interrupt: 300 at memcpy_power7+0x20c/0x840 [ 367.864726] LR = tcmu_queue_cmd+0x844/0xa80 [target_core_user] [ 367.864732] [c0000000fc657800] [d0000000088916d8] tcmu_queue_cmd+0x768/0xa80 [target_core_user] (unreliable) [ 367.864746] [c0000000fc657940] [d000000002993184] __target_execute_cmd+0x54/0x150 [target_core_mod] [ 367.864758] [c0000000fc657970] [d000000002994708] transport_generic_new_cmd+0x158/0x2d0 [target_core_mod] [ 367.864770] [c0000000fc6579f0] [d0000000029948e4] transport_handle_cdb_direct+0x64/0xd0 [target_core_mod] [ 367.864783] [c0000000fc657a60] [d000000002994af8] target_submit_cmd_map_sgls+0x1a8/0x320 [target_core_mod] [ 367.864796] [c0000000fc657af0] [d000000002994cb8] target_submit_cmd+0x48/0x60 [target_core_mod] [ 367.864803] [c0000000fc657b90] [d000000002a54bd0] ibmvscsis_scheduler+0x350/0x5c0 [ibmvscsis] [ 367.864808] [c0000000fc657c50] [c0000000000f1c28] process_one_work+0x1e8/0x5b0 [ 367.864813] [c0000000fc657ce0] [c0000000000f2098] worker_thread+0xa8/0x650 [ 367.864818] [c0000000fc657d80] [c0000000000fa864] kthread+0x114/0x140 [ 367.864823] [c0000000fc657e30] [c0000000000098f0] ret_from_kernel_thread+0x5c/0x6c [ 367.864827] Instruction dump: [ 367.864829] 60420000 7fe3fb78 4bfcd175 60000000 4bfffecc 7c0802a6 f8010010 60000000 [ 367.864838] 7c0802a6 f8010010 f821ffe1 e9230690 38210020 e8010010 7c0803a6 [ 367.864847] ---[ end trace 8d085df7e65f7d20 ]--- [ 367.870358] [ 367.870362] Fixing recursive fault but reboot is needed! [ 388.859695] INFO: rcu_sched detected stalls on CPUs/tasks: [ 388.859717] 16-...: (0 ticks this GP) idle=7e3/140000000000000/0 softirq=12245/12245 fqs=2622 [ 388.859722] (detected by 20, t=5252 jiffies, g=12458, c=12457, q=2904) [ 388.859744] Task dump for CPU 16: [ 388.859747] kworker/16:2 D 0000000000000000 0 6865 0 0x00000800 [ 388.859762] Call Trace: [ 388.859768] [c0000000fc6579a0] [c0000000014ef090] sysctl_sched_migration_cost+0x0/0x4 (unreliable) [ 388.859778] [c0000000fc6579c0] [d000000008890c1c] tcmu_parse_cdb+0x2c/0x40 [target_core_user] [ 388.859782] [c0000000fc6579e0] [c0000000fc657a60] 0xc0000000fc657a60 Reported-by: Bryant G. Ly Signed-off-by: Xiubo Li --- drivers/target/target_core_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 930800c..86a845a 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -437,7 +437,7 @@ static int scatter_data_area(struct tcmu_dev *udev, to_offset = get_block_offset_user(udev, dbi, block_remaining); offset = DATA_BLOCK_SIZE - block_remaining; - to = (void *)(unsigned long)to + offset; + to = (void *)((unsigned long)to + offset); if (*iov_cnt != 0 && to_offset == iov_tail(udev, *iov)) { @@ -510,7 +510,7 @@ static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd, copy_bytes = min_t(size_t, sg_remaining, block_remaining); offset = DATA_BLOCK_SIZE - block_remaining; - from = (void *)(unsigned long)from + offset; + from = (void *)((unsigned long)from + offset); tcmu_flush_dcache_range(from, copy_bytes); memcpy(to + sg->length - sg_remaining, from, copy_bytes);