From patchwork Wed Aug 23 20:37:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helge Deller X-Patchwork-Id: 9918341 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 35390600C5 for ; Wed, 23 Aug 2017 20:37:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2745628A20 for ; Wed, 23 Aug 2017 20:37:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1BDE328A47; Wed, 23 Aug 2017 20:37:11 +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,FREEMAIL_FROM, 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 3858A28A20 for ; Wed, 23 Aug 2017 20:37:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754156AbdHWUhI (ORCPT ); Wed, 23 Aug 2017 16:37:08 -0400 Received: from mout.gmx.net ([212.227.17.22]:50475 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751728AbdHWUhH (ORCPT ); Wed, 23 Aug 2017 16:37:07 -0400 Received: from ls3530.fritz.box ([193.159.16.22]) by mail.gmx.com (mrgmx102 [212.227.17.168]) with ESMTPSA (Nemesis) id 0LosFD-1d4yv619tj-00gqIT; Wed, 23 Aug 2017 22:37:03 +0200 Date: Wed, 23 Aug 2017 22:37:00 +0200 From: Helge Deller To: Al Viro , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, akpm@linux-foundation.org Cc: John David Anglin , linux-parisc@vger.kernel.org Subject: [PATCH v2] fs/select: Fix memory corruption in compat_get_fd_set() Message-ID: <20170823203700.GA29614@ls3530.fritz.box> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.8.3 (2017-05-23) X-Provags-ID: V03:K0:rE8XRVICLqVllpAEWe9f/7edpvfzj3+akrNcPxONUO0jrPJwmIR BPiIuimXSKqUgVmLFmv5R/xFiqbnLS7DD4uRrSkK2F1rv3Ct5ZDB7hux7RNjNS6VX6xKpig 9vcomKkMj1tib4XRpPWB47Q+/54fS5C+EBfJNB926m3BgozAf7ND27p68yFgMVKQituQje1 gRmbyslnHZvkS7q8d65FQ== X-UI-Out-Filterresults: notjunk:1; V01:K0:ddUCsPUaWRw=:kp+DOTwfXUDSuHITbA4ooL HHSaycMsMsS3mZAK19Ru7ppKpS88I89Hd7nYHDiSCznfduxKPo/9tV3vKn8cTrGDoKo1t95m1 nm6BO/fcMa20ZfbMmf06gVsBuCMzPbla8R1UiaEZcSGMnUTzlQuOzuc3VoW46zE0gqEbMxxIL 6ARpfsYY69yxAYvcz5Asr3G77v4jctXIvO10s0HOYvAX4zN+uceazFpdqPqoiJHuOJBsz1XNu m7/ns8CFsPVURO7spdJLXC62pvWDVt8SKuMm04+TA8+Azh7WNf1iEeIJsqZBPzfBU/rXfDy71 EqsOaYap0gc9B5xQClzbFmLAIVle/WZ43X7i331RP3AFEEKmkBXGQ0+ksmF6vMaGESS+eFmjm CBIEG1uzUfQlKDu85By/iLimn5DLxrQ+8ibYsQgZomm5zrGn6n+37/fcCrCxhOx4p6yzOoWKG I4dUg3RYHb/FaNRvo8wkMeE+Ax6ONkJHuJLBcQhPQpEbKr2sbACdeFIpD2aGBe3JRrCkcezKY tKNVOEY6E3oES8E94+arVwX7noY93SFiAYALAGb2gOTgte0cGiHp4hp0jE0fr9/NghvQq8ANq 0NFQI+dAV/+zP7JqGUpfjuwofgbtzzZW0vnvXDowgXdbCJwiow5l1UlZHyr4moneujTGX27sU w3dnWLQ8txkDonOczn2khIfM6cAvCpLXoD8v4zi2biTvTYDVGPAliEAcHE/jhgFXWtcr6dPFm sE5yTDA/XqeatIH+Bw3DhJN/Rdh3Imc2+vLMrAoGLv8jMWIX5wXUIq3Yg9EUIVod2Ju7Sd1iR ySrpVFXneI2W2YDSGyPl0HRh8ERlw== Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Commit 464d62421cb8 ("select: switch compat_{get,put}_fd_set() to compat_{get,put}_bitmap()") changed the calculation on how many bytes need to be zeroed when userspace handed over a NULL pointer for a fdset array in the select syscall. The calculation was changed in compat_get_fd_set() wrongly from memset(fdset, 0, ((nr + 1) & ~1)*sizeof(compat_ulong_t)); to memset(fdset, 0, ALIGN(nr, BITS_PER_LONG)); The ALIGN(nr, BITS_PER_LONG) calculates the number of bits which need to be zeroed in the target fdset array (rounded up to the next full bits for an unsigned long). But the memset() call expects the number of bytes to be zeroed. This leads to clearing more memory than wanted (on the stack area or even at kmalloc()ed memory areas) and to random kernel crashes as we have seen them on the parisc platform. The correct change should have been memset(fdset, 0, (ALIGN(nr, BITS_PER_LONG) / BITS_PER_LONG) * BYTES_PER_LONG); which is the same as can be archieved with a call to zero_fd_set(nr, fdset). Fixes: 464d62421cb8 ("select: switch compat_{get,put}_fd_set() to compat_{get,put}_bitmap()" Cc: Al Viro Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Helge Deller --- Changes between v1 and v2 of the patch: - Rephrased description of the problem diff --git a/fs/select.c b/fs/select.c index 9d5f15e..c6362e3 100644 --- a/fs/select.c +++ b/fs/select.c @@ -1164,11 +1164,7 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, if (ufdset) { return compat_get_bitmap(fdset, ufdset, nr); } else { - /* Tricky, must clear full unsigned long in the - * kernel fdset at the end, ALIGN makes sure that - * actually happens. - */ - memset(fdset, 0, ALIGN(nr, BITS_PER_LONG)); + zero_fd_set(nr, fdset); return 0; } }