From patchwork Mon Apr 30 09:09:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 134697 Delivered-To: patch@linaro.org Received: by 10.46.151.6 with SMTP id r6csp3528047lji; Mon, 30 Apr 2018 02:14:10 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrmGZaM0HNqQ0gGrYZwan2rUPoD5XRD+yuNt+7LtmYOSSnke8E12GpVKkuN/ovQyjoNZE9q X-Received: by 2002:a0c:d88f:: with SMTP id q15-v6mr10462063qvj.83.1525079650630; Mon, 30 Apr 2018 02:14:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525079650; cv=none; d=google.com; s=arc-20160816; b=oW1fbh6q08d5zsD5NXwws3IulELyv8joKWSW9JqBXyiiLl8NQkpu53mGU1dBkYDDfh zI0THZmf7PKOZmD+eO5TDef313rBFpkoeV8QExB7lpXlBfFUK/A4BhO6ToAi7QAe701b lHuO7mlTnSvgH2ysOCgAPg0n/2pYyp1Nc01Y0OOlL6qfiNSewUtLHwzHl4NHTT6eUZiJ SavLAuIGmhYFV1BvH3cUd/5YO4xeqeXAw4sLZA3Bdk9KpV/1gSlaaRVD9+7XmjIgADwz +IdX0bf7WvloAMMWZDAUTC3igmfMMJWlBxzKBzvkHMuJ7hmds5tigsufUff7/KBMkbDl R4yA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:arc-authentication-results; bh=naKBRgLgRvEZKueT5ba2ZxsV2nkBvp6ahOHhJl4ISls=; b=CCSOHLM8nxonxRO2FDZm6UnwSsxxWyQmswId5rVJbzP2WZ61o79nqCGTdS4YX7agOD 4mXUAegL1g8vZg3dzz+fVoZJXLxcZA8CSBgtjwxQ+XnsbsIS0nOlnhrmxh8/iMhN7Mvx pUWyzh8WaH5SY8rol6RaP7je+t/Qk5qoJjsJhSCdlJURPGnuYxJGiDjHNsoEle7T3JWJ Pj+Wnl+ryAEyuiotVJlhgHwnRAmIVTggT88tApxy9V642hIwRbdV+sFhUGQDmBbncAwl pIR9tmp4T8dDM3cUkuH9ssXSziZ0tSbWVIHt4sVMEZQBSJKKOIKr+Xg9sa09eXu2OhGg sVAg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id d16si1699017qkb.67.2018.04.30.02.14.10 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 30 Apr 2018 02:14:10 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:58524 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fD4ss-0007h5-1H for patch@linaro.org; Mon, 30 Apr 2018 05:14:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32799) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fD4q0-0006GZ-Oy for qemu-devel@nongnu.org; Mon, 30 Apr 2018 05:11:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fD4pz-00066O-7J for qemu-devel@nongnu.org; Mon, 30 Apr 2018 05:11:12 -0400 Received: from mout.kundenserver.de ([212.227.17.10]:38655) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fD4pu-0005wL-F1; Mon, 30 Apr 2018 05:11:06 -0400 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue102 [212.227.15.183]) with ESMTPSA (Nemesis) id 0LZvn3-1eWKxx4BVV-00liRl; Mon, 30 Apr 2018 11:10:49 +0200 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Mon, 30 Apr 2018 11:09:57 +0200 Message-Id: <20180430091037.13878-3-laurent@vivier.eu> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180430091037.13878-1-laurent@vivier.eu> References: <20180430091037.13878-1-laurent@vivier.eu> X-Provags-ID: V03:K1:hzraixj2punJDMJGXyURqrGKReIz3eZdAgLmZfZTiglEJEeOSXW cCWwP5i6jtdrj9ZWPcLqqVnxMwIfxryvmCLEsLfAkuwqzZlWCFngdx3gq65sSTUpQYrrlWS vkT0Ychst+9cIZpIHroVXpM81h0pUAkUFcscG+1KL9DNMFCugXzSf9ZYMhkMZoxw6FaIRlI 7JWTtMZJRLQR6bZ2cvRXA== X-UI-Out-Filterresults: notjunk:1; V01:K0:l8Mj40g4GGA=:9TX+n1oinjMeum6Q3nnxGo MsOuukazAsXHwwp3TdWNI61RTTll4QkTE/pTPWbIZQ5JmJP4XyvJdjJuZD+iNo4/j7XgRJfRN A4gAYHjSe7KjYUYsU04Qv4VJGR40Pyo3mU53IL5CHXtHtyHIlD5127DxTtZXI6p91W6ZZAIRv bu+P135ys/GTB7Kh5HaGCOMQs6VgCnWmuzxsE81rPfxJaswZrAmAEdArknz40m8aIlf9j2S04 tesNTzzZdPq6La0kGYt4xwznH0tJ/qa8tQilLhJhUO5Mu9/jkGkcj2KKjeYOCxQNNBlxkvxM+ 6F0x2p0fqnw/C79nDNoseap7ZkRgybDn5MK8tZkfsx9CLQfNNms9YLFZf+vcT4ZdEq8ik18/c 2m66VfjJv9+asIaq9leams8RCiXLo1P2CnwfKHEqqO5Q+ITE60xuBZNp2mwh2zGLz0PzHlrFk X7ulwgnpnXjIlo23exkNhCtsaIDCTgT7/Skd6bWw8LAzmbdr9CeX6/5/W3zDiRw1z+hbur6M1 nfCYSzBvCFo7fYUAy2dLT+OcnjFKCOQfrMdmx2eSVyNRg0XmgnisEtHl0amKeuAWfqHvvE3gZ PgTJgIVgk8AEuiWOHoayrAyfwbhpTJ1jskywIgx9iMIt2hEzTvRGz9kK2Zh3hSLXYhtSPCKCY LdCrVCT+NnEkR3uYmFSiQacP4YAt5wqeacuBgVLbicJ1sTdK/I0P8cvaUHh+rXBbiYIg= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.17.10 Subject: [Qemu-devel] [PULL 02/42] linux-user: Fix getdents emulation for 64 bit guest on 32 bit host X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , qemu-s390x@nongnu.org, Riku Voipio , Laurent Vivier , Cornelia Huck Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Peter Maydell Currently we mishandle emulation of the getdents syscall for the case of a 64 bit guest on a 32 bit host -- it defaults into the 'host and guest same size' codepath and generates incorrect structures in the guest buffer. We can't easily handle the 64-on-32 case using the host getdents syscall, because the guest struct dirent is bigger than the host struct dirent, and we might find the host syscall has handed us back more records than we can fit in the guest buffer after conversion. Instead, always emulate 64-on-32 getdents with the host getdents64. This avoids the buffer-overrun problem because a dirent64 struct is always the same size on any host and always larger than any architecture's dirent struct. Reported-by: Henry Wertz Signed-off-by: Peter Maydell Message-Id: <20180419125740.2695-1-peter.maydell@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) -- 2.14.3 diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 643b8833de..404be44ad5 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -259,10 +259,22 @@ static int gettid(void) { return -ENOSYS; } #endif -#if defined(TARGET_NR_getdents) && defined(__NR_getdents) + +/* For the 64-bit guest on 32-bit host case we must emulate + * getdents using getdents64, because otherwise the host + * might hand us back more dirent records than we can fit + * into the guest buffer after structure format conversion. + * Otherwise we emulate getdents with getdents if the host has it. + */ +#if defined(__NR_getdents) && HOST_LONG_BITS >= TARGET_ABI_BITS +#define EMULATE_GETDENTS_WITH_GETDENTS +#endif + +#if defined(TARGET_NR_getdents) && defined(EMULATE_GETDENTS_WITH_GETDENTS) _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count); #endif -#if !defined(__NR_getdents) || \ +#if (defined(TARGET_NR_getdents) && \ + !defined(EMULATE_GETDENTS_WITH_GETDENTS)) || \ (defined(TARGET_NR_getdents64) && defined(__NR_getdents64)) _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count); #endif @@ -10163,7 +10175,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_getdents case TARGET_NR_getdents: -#ifdef __NR_getdents +#ifdef EMULATE_GETDENTS_WITH_GETDENTS #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 { struct target_dirent *target_dirp;