From patchwork Wed Jan 4 18:10:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 711081 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tv09f444Pz9t0q for ; Thu, 5 Jan 2017 05:45:10 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3tv09f3GkxzDqTm for ; Thu, 5 Jan 2017 05:45:10 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org X-Greylist: delayed 2007 seconds by postgrey-1.36 at bilbo; Thu, 05 Jan 2017 05:44:08 AEDT Received: from relay1.mentorg.com (relay1.mentorg.com [192.94.38.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3tv08S6s5JzDqFn for ; Thu, 5 Jan 2017 05:44:08 +1100 (AEDT) Received: from nat-ies.mentorg.com ([192.94.31.2] helo=svr-ies-mbx-01.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1cOq1E-0004sU-4c from joseph_myers@mentor.com ; Wed, 04 Jan 2017 10:10:36 -0800 Received: from digraph.polyomino.org.uk (137.202.0.87) by svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) with Microsoft SMTP Server (TLS) id 15.0.1210.3; Wed, 4 Jan 2017 18:10:32 +0000 Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.86_2) (envelope-from ) id 1cOq16-0003A7-Qk; Wed, 04 Jan 2017 18:10:28 +0000 Date: Wed, 4 Jan 2017 18:10:28 +0000 From: Joseph Myers X-X-Sender: jsm28@digraph.polyomino.org.uk To: , Subject: [PATCH] powerpc: fix 32-bit ppc_fadvise64_64 for 64-bit offset Message-ID: User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 X-Originating-IP: [137.202.0.87] X-ClientProxiedBy: svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) To svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Consider the following test, built for 32-bit powerpc and run under a 32-bit kernel. #define _GNU_SOURCE #include #include #include #include int main (void) { int fd = open ("/dev/null", O_RDWR); int ret = posix_fadvise64 (fd, 0, -1, POSIX_FADV_NORMAL); if (ret == EINVAL) puts ("posix_fadvise64 returned EINVAL as expected"); else printf ("posix_fadvise64 returned %d, expected EINVAL = %d\n", ret, EINVAL); close (fd); return 0; } For 32-bit powerpc, posix_fadvise64 uses the fadvise64_64 syscall. The negative length means it should return EINVAL. That syscall uses the ppc_fadvise64_64 function to rearrange the arguments into the form used by the architecture-independent syscall implementation. That function calls sys_fadvise64. sys_fadvise64 uses type size_t for the length argument, and passes its arguments through to sys_fadvise64_64, which uses type loff_t. This works OK under a 64-bit kernel, where size_t is 64-bit. Under a 32-bit kernel, however, passing the length through sys_fadvise64 results in it being truncated to 32-bit size_t and then zero-extended back to 64-bit, so resulting in 0 rather than EINVAL being returned for the above test. This patch fixes this bug by calling sys_fadvise64_64 directly from ppc_fadvise64_64. Signed-off-by: Joseph Myers --- Please note that I encountered this problem with older kernels, and while the relevant area has not changed recently and the above analysis and this patch are based on current sources, I ran into an unrelated build failure when attempting to build current kernels to test this fix. Thus, the patch should only be applied given testing that the problem is indeed reproducible with current 32-bit kernels and is fixed by this patch. diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index de04c9f..7753f77 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -119,8 +119,8 @@ long ppc64_personality(unsigned long personality) long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low, u32 len_high, u32 len_low) { - return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low, - (u64)len_high << 32 | len_low, advice); + return sys_fadvise64_64(fd, (u64)offset_high << 32 | offset_low, + (u64)len_high << 32 | len_low, advice); } long sys_switch_endian(void)