From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AB7A7C4345F for ; Mon, 15 Apr 2024 09:03:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=9+W3BNnnyxRMpCvjA6GbDqYzT2Wn8iSQmI/jMptH+HU=; b=Fdu2sWwnlphDnr s6uqx/ahNEFb4ANm1MDojKDi7YFhZxJ33EsQSlYbgs8FsNKFmezPsZM8gRROUqEikfPGAyjy7agdL vS9RMPcdcB+p/WJp2TrCG20xomrYl4dcp7lBrIzKIzqh5qmPsQQM0vbWLErfc0E/Ztmo6+Vmt8IrF qZf86fk739bJNu8p927+RUDcBB6EzXbfjLQM08ir2lp7rDse4/xBwIC0BlGAFK42Hi7Gqoo2ygv6I n72uZbDd2sMxln/1Awqv1oY2keKlKftPJNXSScUEJxrBIs2YwtS/FTgyUu70m8+G0fGgZ9QqRJA3T h18tm7tgFvILMuZ6esmw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rwIF6-00000007dqZ-2Zf4; Mon, 15 Apr 2024 09:03:12 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rwIEz-00000007dpq-2Hj9 for linux-arm-kernel@lists.infradead.org; Mon, 15 Apr 2024 09:03:11 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 68E092F4; Mon, 15 Apr 2024 02:03:32 -0700 (PDT) Received: from FVFF77S0Q05N (unknown [10.57.20.152]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B1D283F64C; Mon, 15 Apr 2024 02:03:02 -0700 (PDT) Date: Mon, 15 Apr 2024 10:02:59 +0100 From: Mark Rutland To: "Russell King (Oracle)" , Kees Cook Cc: Tetsuo Handa , Linux ARM , syzbot , linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com Subject: Re: [syzbot] [hardening?] [mm?] BUG: bad usercopy in fpa_set Message-ID: References: <0000000000004cf5c205faf1c7f3@google.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240415_020305_655139_A96A7A3C X-CRM114-Status: GOOD ( 19.25 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Wed, Apr 03, 2024 at 05:12:07PM +0100, Russell King (Oracle) wrote: > On Tue, Mar 05, 2024 at 08:27:07PM +0900, Tetsuo Handa wrote: > > Hello. > > > > syzbot is reporting kernel memory overwrite attempt at fpa_set(). > > I guessed that the amount to copy from/to should be sizeof(union fp_state) > > than sizeof(struct user_fp), for arch_ptrace(PTRACE_[SG]ETFPREGS) for arm > > is using offset == 0 and size == sizeof(union fp_state). But my guess did not > > solve the issue ( https://syzkaller.appspot.com/x/patch.diff?x=11e46dbc180000 ). > > This is silly. > > sizeof(struct user_fp) is: > > 8 * ( > 1 bit for sign1, 15 bits unused => 2 bytes > 1 bit for sign2, 14 bits unused, 1 bit for j => 2 bytes > 31 bits for mantissa1 => 4 bytes > 32 bits for mantissa0 => 4 bytes > ) + > 4 bytes for fpsr > 4 bytes for fpcr > 8 bytes for ftype > 4 bytes for init_flag > > This totals 8 * 12 + 4 + 4 + 8 + 4 = 116 bytes or 29 32-bit quantities, > or 29 "unsigned int"s. > > This is copied into union fp_state. This union is made up of one of > several different formats depending on the FP being used. user_fp > doesn't reflect this. However, one of these, struct fp_soft_struct, > is specifically sized to ensure that user_fp is _smaller_. > > struct fp_soft_struct is 35 unsigned int's. This is 140 bytes. This > is larger than sizeof(user_fp). > > Therefore, there is _no way_ for fpa_set() to overwrite anything > outside of thread_info->fpstate, because sizeof(struct user_fp) > is smaller than sizeof(thread->fpstate). > > Syzbot appears to be wrong in this instance. I believe the problem here is that HARDENED_USERCOPY tries to prevent any usercopy to/from task_struct except for fields that are explicitly whitelisted (which all need to be in one contiguous range). That was added in commit: 5905429ad85657c2 ("fork: Provide usercopy whitelisting for task_struct") However, architectures only have the option to provide arch_thread_struct_whitelist() to whitelist some fields in thread_struct, not thread_info where the fp_state lives. On arm arch_thread_struct_whitelist() whitelists precisely nothing: static inline void arch_thread_struct_whitelist(unsigned long *offset, unsigned long *size) { *offset = *size = 0; } ... which was added in commit: 08626a6056aad824 ("arm: Implement thread_struct whitelist for hardened usercopy") That commit says that all accesses are bounce-buffered and bypass the check, but AFAICT the fpa_set() code hasn't changed since then, so either that was wrong or the user_regset_copyin() code has changed. Kees, I believe you need to look at this. See the dashboard page at: https://syzkaller.appspot.com/bug?extid=cb76c2983557a07cdb14 Mark. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel