From patchwork Tue Sep 15 03:01:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen Gang X-Patchwork-Id: 517650 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 73A4C140129 for ; Tue, 15 Sep 2015 13:02:12 +1000 (AEST) Received: from localhost ([::1]:44716 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZbgVV-0008O3-Uj for incoming@patchwork.ozlabs.org; Mon, 14 Sep 2015 23:02:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42730) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZbgVG-00086H-06 for qemu-devel@nongnu.org; Mon, 14 Sep 2015 23:01:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZbgVB-00081O-0r for qemu-devel@nongnu.org; Mon, 14 Sep 2015 23:01:53 -0400 Received: from smtpbg298.qq.com ([184.105.67.102]:45006) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZbgVA-00080z-Pk for qemu-devel@nongnu.org; Mon, 14 Sep 2015 23:01:48 -0400 X-QQ-mid: esmtp31t1442286089t976t31079 Received: from localhost.localdomain (unknown [36.110.17.42]) by esmtp4.qq.com (ESMTP) with id ; Tue, 15 Sep 2015 11:01:21 +0800 (CST) X-QQ-SSF: 01000000000000F0FG500500002000H X-QQ-GoodBg: 0 X-QQ-CSender: gang.chen.5i5j@qq.com From: gang.chen.5i5j@gmail.com To: riku.voipio@iki.fi Date: Tue, 15 Sep 2015 11:01:17 +0800 Message-Id: <1442286077-10129-1-git-send-email-gang.chen.5i5j@gmail.com> X-Mailer: git-send-email 1.9.1 X-QQ-SENDSIZE: 520 X-QQ-FName: D44081825C7B473BB128DEB2B056A916 X-QQ-LocalIP: 163.177.66.155 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 184.105.67.102 Cc: peter.maydell@linaro.org, Chen Gang , qemu-devel@nongnu.org, xili_gchen_5257@hotmail.com, rth@twiddle.net Subject: [Qemu-devel] [PATCH] linux-user/syscall.c: Fix issue for checking ptr in different address spaces in TARGET_CMSG_NXTHDR X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Chen Gang After fix this issue, qemu can run i386 wine notepad.exe successfully. But the initialization performance is not quite well. Signed-off-by: Chen Gang --- linux-user/syscall.c | 30 +++++++++++++++++------------- linux-user/syscall_defs.h | 20 +++++++++----------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 973cc2f..521749c 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1181,17 +1181,18 @@ static inline abi_long target_to_host_cmsg(struct msghdr *msgh, struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); abi_long msg_controllen; abi_ulong target_cmsg_addr; - struct target_cmsghdr *target_cmsg; + struct target_cmsghdr *target_cmsg, *base; socklen_t space = 0; msg_controllen = tswapal(target_msgh->msg_controllen); if (msg_controllen < sizeof (struct target_cmsghdr)) goto the_end; target_cmsg_addr = tswapal(target_msgh->msg_control); - target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1); - if (!target_cmsg) + base = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1); + if (!base) { return -TARGET_EFAULT; - + } + target_cmsg = base; while (cmsg && target_cmsg) { void *data = CMSG_DATA(cmsg); void *target_data = TARGET_CMSG_DATA(target_cmsg); @@ -1247,7 +1248,7 @@ static inline abi_long target_to_host_cmsg(struct msghdr *msgh, } cmsg = CMSG_NXTHDR(msgh, cmsg); - target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg); + target_cmsg = TARGET_CMSG_NXTHDR(base, msg_controllen, target_cmsg); } unlock_user(target_cmsg, target_cmsg_addr, 0); the_end: @@ -1259,19 +1260,22 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh, struct msghdr *msgh) { struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); - abi_long msg_controllen; + abi_long msg_controllen, size; abi_ulong target_cmsg_addr; - struct target_cmsghdr *target_cmsg; + struct target_cmsghdr *target_cmsg, *base; socklen_t space = 0; - msg_controllen = tswapal(target_msgh->msg_controllen); - if (msg_controllen < sizeof (struct target_cmsghdr)) + size = tswapal(target_msgh->msg_controllen); + if (size < sizeof(struct target_cmsghdr)) { goto the_end; + } target_cmsg_addr = tswapal(target_msgh->msg_control); - target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0); - if (!target_cmsg) + base = lock_user(VERIFY_WRITE, target_cmsg_addr, size, 0); + if (!base) { return -TARGET_EFAULT; - + } + msg_controllen = size; + target_cmsg = base; while (cmsg && target_cmsg) { void *data = CMSG_DATA(cmsg); void *target_data = TARGET_CMSG_DATA(target_cmsg); @@ -1389,7 +1393,7 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh, msg_controllen -= tgt_space; space += tgt_space; cmsg = CMSG_NXTHDR(msgh, cmsg); - target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg); + target_cmsg = TARGET_CMSG_NXTHDR(base, size, target_cmsg); } unlock_user(target_cmsg, target_cmsg_addr, space); the_end: diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 5256fe5..aec2f23 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -234,7 +234,8 @@ struct target_cmsghdr { }; #define TARGET_CMSG_DATA(cmsg) ((unsigned char *) ((struct target_cmsghdr *) (cmsg) + 1)) -#define TARGET_CMSG_NXTHDR(mhdr, cmsg) __target_cmsg_nxthdr (mhdr, cmsg) +#define TARGET_CMSG_NXTHDR(base, size, cmsg) __target_cmsg_nxthdr(base, size, \ + cmsg) #define TARGET_CMSG_ALIGN(len) (((len) + sizeof (abi_long) - 1) \ & (size_t) ~(sizeof (abi_long) - 1)) #define TARGET_CMSG_SPACE(len) (TARGET_CMSG_ALIGN (len) \ @@ -242,17 +243,14 @@ struct target_cmsghdr { #define TARGET_CMSG_LEN(len) (TARGET_CMSG_ALIGN (sizeof (struct target_cmsghdr)) + (len)) static __inline__ struct target_cmsghdr * -__target_cmsg_nxthdr (struct target_msghdr *__mhdr, struct target_cmsghdr *__cmsg) +__target_cmsg_nxthdr(void *base, abi_long size, struct target_cmsghdr *msg) { - struct target_cmsghdr *__ptr; - - __ptr = (struct target_cmsghdr *)((unsigned char *) __cmsg - + TARGET_CMSG_ALIGN (tswapal(__cmsg->cmsg_len))); - if ((unsigned long)((char *)(__ptr+1) - (char *)(size_t)tswapal(__mhdr->msg_control)) - > tswapal(__mhdr->msg_controllen)) - /* No more entries. */ - return (struct target_cmsghdr *)0; - return __cmsg; + msg = (struct target_cmsghdr *)((unsigned char *)msg + + TARGET_CMSG_ALIGN(tswapal(msg->cmsg_len))); + if ((unsigned long)((char *)(msg + 1) - (char *)base) > size) { + return NULL; + } + return msg; } struct target_mmsghdr {