From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) by sourceware.org (Postfix) with ESMTPS id 1624E3839D07 for ; Tue, 13 Dec 2022 20:12:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1624E3839D07 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=jguk.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=jguk.org Received: by mail-wr1-x434.google.com with SMTP id h10so16951373wrx.3 for ; Tue, 13 Dec 2022 12:12:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jguk.org; s=google; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=iTdXxgCzDBQL38OJ4+08uY1HsGCUNQ+bqi0fs5V2u3A=; b=MD/Y9uslXex3RcBbNYXAXn8jeMVuNrX/HBMpIY/9l64Ha1WZ9IiBsxT3BONQy3EW7B tDWSKJq/QDWUiWhnu4d9GihWHq93i5ichhZG9qyv3NgFvCNXRv6P9wqpaC9jRw5pMroR PlnMPCjxkcT116WQaPl8IrbFfbXepoinolAhPMs5R3cGkm3b8ClPnUUvze4V7c+RDJgM mdwMBHg6GmceXB1MTuW0umYld8QdtnLAqp+XLRLrkeOf/uACj2Eh7j83VT8Sp7e9JhNJ mImgUUI0ov7gI5iRG3PmPj2RUT2hsVp664gnFHz1hJs35QVm0NjsHdQ+q2EunvRo8GLe eljQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=iTdXxgCzDBQL38OJ4+08uY1HsGCUNQ+bqi0fs5V2u3A=; b=NecVLVZP7o5K3ZVwxOo/5KaoXWmdBtMjusjrnOUydsSpEPCrWf3MCZBoWcoLeBLn2q ENwq8gB7XVvqarr8epGyIdEcYOmbCKTAwrJRpD5UuJpn2gDZR4pa66yf8Yht2qDiOPZ7 vBYrOm1KJ/Zn9CScwBCISXe8UJq4wFL2iCiSTKx/dzmY72tZEBZtY7Lfd4No5ROIYkMM KN5EM6NQrcWPUJPEbuO5R4Mu0opg6ROXDLvbRlidBEBeaSrg+mW05R6esANV2o/chare CceKk8CjOikpALAcYsncLM6G7y9ldRPX5YiYoRgPr/wf9xOzKTGjH6STtDB6QsAZq61t 3wAA== X-Gm-Message-State: ANoB5pkhmD6Cdbx+jQDbpUp3vZKNtFOQaq6GfzGe417hitoXDkR9DQhf E9VdhINRHh1Qt/62e9T83dwsww== X-Google-Smtp-Source: AA0mqf6M+ZEmFBsCUK1M8jWtHiyDgRAfFnJCB8xHqeVOcQ/g8bTCFpcCjUdmXMJbhOHinjonNP6Ilg== X-Received: by 2002:adf:cc92:0:b0:242:865d:e8d8 with SMTP id p18-20020adfcc92000000b00242865de8d8mr14813172wrj.55.1670962344437; Tue, 13 Dec 2022 12:12:24 -0800 (PST) Received: from [192.168.0.12] (cpc87345-slou4-2-0-cust172.17-4.cable.virginm.net. [81.101.252.173]) by smtp.gmail.com with ESMTPSA id j14-20020adfea4e000000b00236c1f2cecesm782530wrn.81.2022.12.13.12.12.23 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 13 Dec 2022 12:12:24 -0800 (PST) Message-ID: <68c69b5a-e6e7-7021-5f98-37ba8f3c49eb@jguk.org> Date: Tue, 13 Dec 2022 20:12:23 +0000 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.2 Subject: Re: Avoiding stack buffer clear being optimised out To: Jonathan Wakely Cc: gcc-help References: <4366aeb5-7fdb-6fa4-b0f5-ebe74c1d4fb2@jguk.org> Content-Language: en-GB From: Jonny Grant In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-3.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 30/11/2022 17:40, Jonathan Wakely wrote: > On Wed, 30 Nov 2022 at 16:27, Jonny Grant wrote: >> >> Hello >> >> Does GCC have a clear way to avoid memset being compiled out by optimiser? >> >> This article came up, so I combined the broken.c with GCC >> gcc -Wall -O2 -o broken broken.c >> >> Note, I've been using gcc for many years, I'm not looking for just tips how to compile code. I only want to discuss this optimiser issue :-) >> >> https://blog.cloudflare.com/the-linux-kernel-key-retention-service-and-why-you-should-use-it-in-your-next-application/ >> >> If I modify to clear the buffer, it gets removed by the compiler >> >> The only way I could get it to not remove the memset is by adding another printf, (propagating a return code after checking memset wasn't enough) > > This is simpler and works for me, but I'm not sure if it's guaranteed > to always work: > > __attribute__((noinline,noipa)) > void wipe(void* p, size_t n) > { > memset(p, 0, n); > } > > static int encrypt(void) > { > uint8_t key[] = "hunter2"; > printf("encrypting with super secret key: %s\n", key); > wipe(key, 8); > } > > There is discussion of alternatives in > https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1358.pdf (starting > on page 6). > > The memset_s function was added to C in Annex K, but most > implementations of the C library do not support Annex K. Jonathan I wonder if you know how GCC decides to remove the memset? In the following example, the memset even changes the bytes on the stack, which are then not changed later on in the program, rather strange. If I modify the code to check the buffer contains key[0] as nul byte, it still shows as 0, but then the stack is still readable // gcc -Wall -O2 -o broken broken.c #include #include #include static int encrypt(void) { uint8_t key[] = "hunter2"; printf("encrypting with super secret key: %s\n", key); memset(key, 0, 8); if(key[0] == '\0') return 0; else return 1; } static void log_completion(void) { /* oh no, we forgot to init the msg */ char msg[8]; printf("not important, just fyi: %s\n", msg); } int main(void) { int ret = encrypt(); /* notify that we're done */ log_completion(); printf("ret: %d\n", ret); return ret; }