From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JM7XA-0006ki-Nl for qemu-devel@nongnu.org; Mon, 04 Feb 2008 15:03:16 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JM7X9-0006iT-6H for qemu-devel@nongnu.org; Mon, 04 Feb 2008 15:03:16 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JM7X8-0006i0-SJ for qemu-devel@nongnu.org; Mon, 04 Feb 2008 15:03:14 -0500 Received: from tim.rpsys.net ([194.106.48.114]) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1JM7X7-0006vY-DQ for qemu-devel@nongnu.org; Mon, 04 Feb 2008 15:03:13 -0500 Received: from localhost (localhost [127.0.0.1]) by tim.rpsys.net (8.13.6/8.13.8) with ESMTP id m14K3AAj022359 for ; Mon, 4 Feb 2008 20:03:10 GMT Received: from tim.rpsys.net ([127.0.0.1]) by localhost (tim.rpsys.net [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 22116-06 for ; Mon, 4 Feb 2008 20:03:06 +0000 (GMT) Received: from [192.168.1.15] (max.rpnet.com [192.168.1.15]) (authenticated bits=0) by tim.rpsys.net (8.13.6/8.13.8) with ESMTP id m14K321a022350 (version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NO) for ; Mon, 4 Feb 2008 20:03:02 GMT From: Richard Purdie Content-Type: text/plain Date: Mon, 04 Feb 2008 20:03:02 +0000 Message-Id: <1202155382.4788.95.camel@localhost.localdomain> Mime-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] Fix writev syscall emulation Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Hi, OpenEmbedded/Poky use qemu for locale generation when cross compiling. When we upgraded to qemu 0.9.1 it started giving locale generation errors on all 64 bit machines and some 32 bit ones. I've traced it to the writev syscall failing. localedef passes several { NULL, 0 } iovec entries which trip up lock_iovec(). That function is returning an error for these but the return value isn't checked. The syscall is therefore always made but sometimes with a iovec that has only been half copied. If the total writes exceed size_t, EINVAL is returned by the kernel and glibc code emulates the call with a write which is most likely to happen on 32 bit so it sometimes works. size_t is unlikely to be exceeded on 64 bit so that returns an EFAULT and always corrupts/fails. Anyhow, it seems 0 length iovec entries are allowed and we shouldn't care about the addresses in those cases. The patch below is one way to fix this. Ideally the return value of lock_iovec() needs be be checked too. Regards, Richard --- linux-user/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: qemu-0.9.1/linux-user/syscall.c =================================================================== --- qemu-0.9.1.orig/linux-user/syscall.c 2008-02-03 00:00:00.000000000 +0000 +++ qemu-0.9.1/linux-user/syscall.c 2008-02-03 00:00:38.000000000 +0000 @@ -1048,7 +1048,7 @@ static abi_long lock_iovec(int type, str base = tswapl(target_vec[i].iov_base); vec[i].iov_len = tswapl(target_vec[i].iov_len); vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); - if (!vec[i].iov_base) + if (!vec[i].iov_base && vec[i].iov_len) goto fail; } unlock_user (target_vec, target_addr, 0);