Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp3514imw; Tue, 12 Jul 2022 13:20:46 -0700 (PDT) X-Google-Smtp-Source: AGRyM1v48XGB9LJe3KZ9YXKCK9GnoIcmsW+CLJoNl4ptvUr/Cchxo7lFWMQYxp/B8gQWRqHYKrmG X-Received: by 2002:a17:907:75e3:b0:72b:198a:b598 with SMTP id jz3-20020a17090775e300b0072b198ab598mr26428562ejc.401.1657656812121; Tue, 12 Jul 2022 13:13:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657656812; cv=none; d=google.com; s=arc-20160816; b=y4AGTScvH4o6WHIGj1V4rkV3KX1pKkz6re/n7Npicnjrumjz6twIueazGYK/b2f+yL CvP9jN53TWlX4roFThwmpJo4wIpoyh05gIqAzLR2A4fkmtbd7bm+MX+Ag6Ad/IsGHaof SPBsu8CXDprneKQQk5iiEy2lOljM1puBByCW+I7fL/cDWs81+pu7alUC5GFois1TC3r/ b+n2+71nsVQa4J02KlTdnVSZhMLHBBTOuokXllwhbOU8Yl1gLCyzrZWcw0GNvYzeFutY Zxqrg9TSwGSDw0hKZgKR2/ZnVjZpn1WDyfeIG9VWtD450g3PECbpuEfbh+c6tnaiLtfk E7kg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=dZN4uuxPpHDLHHN5iG2K/mDgJM5TkDtpF3An+uM5PBo=; b=q8gEEam0JrzT2k7rC5o0F/oBwkbk86mTpQTNUgi+VtMAWEzIlO9qm6oEi2l2k9LnTK f+BhGjuXYtvepvlnogzK/m9jvghakOSr8lHE5SdN4jr2Fbao7RhrRTImMybHxiJoyPC7 zz4i7t/FLL0JYOZ/Tp162RSoqPl7AvY5ug7HGZYCkjjjOprW1USfPySxP1qo2xpnY0fe hv9WtwehQ+qm8lSlV3uC0d6RdcSfQxbkCGTUhXv/W0/CfuZ2gcL5ikoMAivN1RfsOJ2f k5Z8CO0VAHUaUDoc+0FQstaQR9wiNyWjGAG0VN0obP1PYO/pJHsXaeawypvmR8HNfDRh R9Fw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="2Xp/yOGC"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id f22-20020a0564021e9600b0043adbbf1040si3955201edf.167.2022.07.12.13.12.52; Tue, 12 Jul 2022 13:13:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="2Xp/yOGC"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234533AbiGLStJ (ORCPT + 99 others); Tue, 12 Jul 2022 14:49:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45896 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234451AbiGLSru (ORCPT ); Tue, 12 Jul 2022 14:47:50 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 435E0DE9DE; Tue, 12 Jul 2022 11:43:26 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 4BB4161AC9; Tue, 12 Jul 2022 18:43:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0BCA0C341C8; Tue, 12 Jul 2022 18:43:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1657651400; bh=jXkipwUJuN5Bshbw5oq+n7KCie4OGQQnZ71o0LvNP0o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=2Xp/yOGCIk169K4vVsv7E3mKzQSeOFjAqiHER7euNiZrcQ2RO3SbEWHnactUWFAaf lv4PWZrMG7hkaZq1QygsPTmT/Xr5eU9Sb1ZH6EGNH3cYhCCoCEGNlRRMhAYTIkAA9h s5cSlHZZ5DoGOmzS0cEZwm2npgkN1z7vsCmuNq0c= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "Peter Zijlstra (Intel)" , Borislav Petkov , Sasha Levin , Ben Hutchings Subject: [PATCH 5.10 064/130] x86/alternative: Relax text_poke_bp() constraint Date: Tue, 12 Jul 2022 20:38:30 +0200 Message-Id: <20220712183249.417216813@linuxfoundation.org> X-Mailer: git-send-email 2.37.0 In-Reply-To: <20220712183246.394947160@linuxfoundation.org> References: <20220712183246.394947160@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Peter Zijlstra commit 26c44b776dba4ac692a0bf5a3836feb8a63fea6b upstream. Currently, text_poke_bp() is very strict to only allow patching a single instruction; however with straight-line-speculation it will be required to patch: ret; int3, which is two instructions. As such, relax the constraints a little to allow int3 padding for all instructions that do not imply the execution of the next instruction, ie: RET, JMP.d8 and JMP.d32. While there, rename the text_poke_loc::rel32 field to ::disp. Note: this fills up the text_poke_loc structure which is now a round 16 bytes big. [ bp: Put comments ontop instead of on the side. ] Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Borislav Petkov Link: https://lore.kernel.org/r/20211204134908.082342723@infradead.org Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/alternative.c | 49 +++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 15 deletions(-) --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -1243,10 +1243,13 @@ void text_poke_sync(void) } struct text_poke_loc { - s32 rel_addr; /* addr := _stext + rel_addr */ - s32 rel32; + /* addr := _stext + rel_addr */ + s32 rel_addr; + s32 disp; + u8 len; u8 opcode; const u8 text[POKE_MAX_OPCODE_SIZE]; + /* see text_poke_bp_batch() */ u8 old; }; @@ -1261,7 +1264,8 @@ static struct bp_patching_desc *bp_desc; static __always_inline struct bp_patching_desc *try_get_desc(struct bp_patching_desc **descp) { - struct bp_patching_desc *desc = __READ_ONCE(*descp); /* rcu_dereference */ + /* rcu_dereference */ + struct bp_patching_desc *desc = __READ_ONCE(*descp); if (!desc || !arch_atomic_inc_not_zero(&desc->refs)) return NULL; @@ -1295,7 +1299,7 @@ noinstr int poke_int3_handler(struct pt_ { struct bp_patching_desc *desc; struct text_poke_loc *tp; - int len, ret = 0; + int ret = 0; void *ip; if (user_mode(regs)) @@ -1335,8 +1339,7 @@ noinstr int poke_int3_handler(struct pt_ goto out_put; } - len = text_opcode_size(tp->opcode); - ip += len; + ip += tp->len; switch (tp->opcode) { case INT3_INSN_OPCODE: @@ -1351,12 +1354,12 @@ noinstr int poke_int3_handler(struct pt_ break; case CALL_INSN_OPCODE: - int3_emulate_call(regs, (long)ip + tp->rel32); + int3_emulate_call(regs, (long)ip + tp->disp); break; case JMP32_INSN_OPCODE: case JMP8_INSN_OPCODE: - int3_emulate_jmp(regs, (long)ip + tp->rel32); + int3_emulate_jmp(regs, (long)ip + tp->disp); break; default: @@ -1431,7 +1434,7 @@ static void text_poke_bp_batch(struct te */ for (do_sync = 0, i = 0; i < nr_entries; i++) { u8 old[POKE_MAX_OPCODE_SIZE] = { tp[i].old, }; - int len = text_opcode_size(tp[i].opcode); + int len = tp[i].len; if (len - INT3_INSN_SIZE > 0) { memcpy(old + INT3_INSN_SIZE, @@ -1508,21 +1511,37 @@ static void text_poke_loc_init(struct te const void *opcode, size_t len, const void *emulate) { struct insn insn; - int ret; + int ret, i; memcpy((void *)tp->text, opcode, len); if (!emulate) emulate = opcode; ret = insn_decode_kernel(&insn, emulate); - BUG_ON(ret < 0); - BUG_ON(len != insn.length); tp->rel_addr = addr - (void *)_stext; + tp->len = len; tp->opcode = insn.opcode.bytes[0]; switch (tp->opcode) { + case RET_INSN_OPCODE: + case JMP32_INSN_OPCODE: + case JMP8_INSN_OPCODE: + /* + * Control flow instructions without implied execution of the + * next instruction can be padded with INT3. + */ + for (i = insn.length; i < len; i++) + BUG_ON(tp->text[i] != INT3_INSN_OPCODE); + break; + + default: + BUG_ON(len != insn.length); + }; + + + switch (tp->opcode) { case INT3_INSN_OPCODE: case RET_INSN_OPCODE: break; @@ -1530,7 +1549,7 @@ static void text_poke_loc_init(struct te case CALL_INSN_OPCODE: case JMP32_INSN_OPCODE: case JMP8_INSN_OPCODE: - tp->rel32 = insn.immediate.value; + tp->disp = insn.immediate.value; break; default: /* assume NOP */ @@ -1538,13 +1557,13 @@ static void text_poke_loc_init(struct te case 2: /* NOP2 -- emulate as JMP8+0 */ BUG_ON(memcmp(emulate, ideal_nops[len], len)); tp->opcode = JMP8_INSN_OPCODE; - tp->rel32 = 0; + tp->disp = 0; break; case 5: /* NOP5 -- emulate as JMP32+0 */ BUG_ON(memcmp(emulate, ideal_nops[NOP_ATOMIC5], len)); tp->opcode = JMP32_INSN_OPCODE; - tp->rel32 = 0; + tp->disp = 0; break; default: /* unknown instruction */