From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1qLdYd-0000pj-U8 for mharc-grub-devel@gnu.org; Tue, 18 Jul 2023 01:47:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qLdYb-0000pY-Ux for grub-devel@gnu.org; Tue, 18 Jul 2023 01:47:34 -0400 Received: from mail-yb1-xb31.google.com ([2607:f8b0:4864:20::b31]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qLdYY-0000SI-EZ for grub-devel@gnu.org; Tue, 18 Jul 2023 01:47:32 -0400 Received: by mail-yb1-xb31.google.com with SMTP id 3f1490d57ef6-cada5e4e3f6so5316727276.3 for ; Mon, 17 Jul 2023 22:47:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=efficientek-com.20221208.gappssmtp.com; s=20221208; t=1689659247; x=1692251247; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=t3ZQjR4PVHsvPEGQl0OVX/mOZMPUG5yJuzeZXS1e67I=; b=wwKQtu1ZmWqLcKMwydh+pdaEDLsE3JQ9UdY8C0ryNgXEURs3Tmia0JB5K/hcXSm2DL UzRT7OHCqjuRs98IM0eaZI+2YeHd5mxTaU2oh0NUMI5hNGXP+DGqn6ZStG91Li4iEimd NNc2+BZqNLLtAuzqWVAtGuZz+t5hWLvmLwiIuXEtDDbK/l596lCLfoZNO2jL6ll4Etq5 wAaQP+qVD+Fa2WYU0XSUMiBiCJGgAReV5oS1Yh5gx0chRmYl+N9Npgej2X1QtlBEiWoD FHQTe5oqcX1mj+7PwUINhrEmlgCNoHZbwHdLGGD357ma/FmLaDAnhO3aRWR3/GzJ06EB dfKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689659247; x=1692251247; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=t3ZQjR4PVHsvPEGQl0OVX/mOZMPUG5yJuzeZXS1e67I=; b=fUqWjAB7afW4ROqwFktMd0QGRy5qbevvTNGKK4TMvjI9mYC8z5R+wRhbjDxzFw7aIv CU559fcTjVQgWjWWW2GLr2RUzaaJmSoOTbt542E5FVsSXCCfEOGiYRT+FM+JrNJdWAQX JWN47HWKmW1XuwEQp+woKybUqSdPKX58vDlHzpUyLYuftzTuN7kbDmiheIzMYflKawTT kaA8wTRvJFt5db0S+m+QGhJuzsVFmC4tVwDtKd4ZaN39ivjEW/I5hAU6vKXMHzoX8sIC R6hQkeO5tu2Mg/Xan079RRUh3ODn0hlmeBANh1rK3umvNoei4/d07OLtizh5BwjFPm0f FC6g== X-Gm-Message-State: ABy/qLZ9EevZ8trapLNeHB5vTkRVK6HnjeLAusXlWKtcOeuxFP4gvgIl KE4D8qst9svHyjKaw0JeLCWcdusmCny8NvAI0IU= X-Google-Smtp-Source: APBJJlHe+d05T/fsH/6sdTPK0pYPYmp/9bZDw93yVB1zggfUmQiXLNFStYrRLnx4mqCpTMujLDwGaw== X-Received: by 2002:a81:4888:0:b0:582:98f9:a1e3 with SMTP id v130-20020a814888000000b0058298f9a1e3mr11640389ywa.18.1689659247511; Mon, 17 Jul 2023 22:47:27 -0700 (PDT) Received: from localhost.localdomain ([37.218.244.249]) by smtp.gmail.com with ESMTPSA id o8-20020a81de48000000b00577335ea38csm271824ywl.121.2023.07.17.22.47.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jul 2023 22:47:26 -0700 (PDT) From: Glenn Washburn To: grub-devel@gnu.org, Daniel Kiper Cc: Ard Biesheuvel , Chris Coulson , Peter Jones , Glenn Washburn Subject: [RFC PATCH] efi: Disable stack smashing protection on grub_efi_init() Date: Tue, 18 Jul 2023 00:47:14 -0500 Message-Id: <20230718054714.3090126-1-development@efficientek.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=2607:f8b0:4864:20::b31; envelope-from=development@efficientek.com; helo=mail-yb1-xb31.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Jul 2023 05:47:34 -0000 GCC is electing to instrument grub_efi_init() to give it stack smashing protection when configuring with --enable-stack-protector on the x86_64-efi target. In the function prologue, the canary at the top of the stack frame is set to the value of the stack guard. And in the epilogue, the canary is checked to verify if it is equal to the guard and if not to call the stack check fail function. The issue is that grub_efi_init() sets up the guard by initializing it with random bytes, if the firmware supports the RNG protocol. So in its prologue the canary will be set with the value of the uninitialized guard, likely NULL bytes. Then the guard is initialized, and finally the epilogue checks the canary against the guard, which will almost certainly be different. This causes the code path for a smashed stack to be taken, causing the machine to print out a message that stack smashing was detected, wait 5 seconds, and then reboot. Disable grub_efi_init() instrumentation so there is no stack smashing false positive generated. Signed-off-by: Glenn Washburn --- I recently discovered that my OVMF (debian version 2020.11-2+deb11u1) was not initializing the stack guard because the firmware was did enable support for the RNG protocol. It turns out that the RNG protocol is not enabled unless a source of randomness is found, which can be added with the QEMU arguments "-device virtio-rng-pci". This issue did not occur when the guard was not initialized in grub_efi_init() because the uninitialized value of the guard would be used for the canary, and sinice nothing changed, the canary and guard would be the same at the end of grub_efi_init(). Initially to solve this, I tried to set the canary in grub_efi_init() after the guard gets initialized. The problem I ran into is that gcc outputs instructions that use the base pointer register as a general purpose register. I couldn't come up with another method of generically figuring out where the start of the frame was so that I could set the canary. The rsp register is offset by the functions local variables which are variable as code is inlined or otherwise changes. Knowing the offset of the stack pointer to the frame start, I could properly set the canary. But again, if local variables are added or subtracted, including in inlined functions called, that offset will need to be regenerated. And its fragile because different verions of GCC or optimization levels may change this offset also. If there was a robust way to set the canary, I think that would be preferable so that we can get stack smashing support on the function. Any one have ideas? Another thing that has troubled me is why has no one else seen this behavior in the last several years that this code has been active? Do distros already have a patch for this? Is the RNG protocol supported by virtual no bare metal firmwares? I don't hit this issue on test machine, so I'm lead to believe that it must not support the RNG protocol (but I've yet to check). Are there other explanations for this that I'm missing? Glenn --- grub-core/kern/efi/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c index 6fe1ff8c868e..e759cc315b85 100644 --- a/grub-core/kern/efi/init.c +++ b/grub-core/kern/efi/init.c @@ -102,7 +102,7 @@ stack_protector_init (void) grub_addr_t grub_modbase; -void +__attribute__ ((__optimize__ ("-fno-stack-protector"))) void grub_efi_init (void) { grub_modbase = grub_efi_section_addr ("mods"); -- 2.34.1