From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [IPv6:2a00:1450:4864:20::629]) by sourceware.org (Postfix) with ESMTPS id 482DD3871D24 for ; Tue, 13 Dec 2022 23:13:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 482DD3871D24 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-ej1-x629.google.com with SMTP id kw15so40481111ejc.10 for ; Tue, 13 Dec 2022 15:13:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=AnIpPZLvdz7ToXszDtFRwZMswe+dU3TDzfV1GSqmWNk=; b=MfruooMRK1FLVyow9gZvPQw2anPQFCGKzNdx+8V+CvyFBkpAqLiT7uRdAix9CsrR0O VSmOU07GxAQWXOR5hdYu/stVF//qUIZEDAHo9kvbZR+JeRwpOGDnJ1okfG9+zjvct4+R 82YAXhiBJ8SPVtG1FxhpNLcOc1i2vJKk08QZSEFTkeF1IVsFTBwUWlcjI7EgWXJ/Jvbn RuAhgegh3PXj9oy5W9PxYEuc+w8SXvZEsvJGN7o11vs9Nb8TdEs08abttXT1Ggb4ZlN/ z6IqQfJtlNdCkmaW60vhfTkjnBAg3mdXZXqCgRjF8xKPeLOq9aggqNckXj6Uv9SdMdqC zZzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AnIpPZLvdz7ToXszDtFRwZMswe+dU3TDzfV1GSqmWNk=; b=7xNYi2+mDo3zrBhcXDr4vYL8MtDfofsi7hDyGQgH+r93tokUMBdEk9N73b9aU9aNva kahfOYbMH6YEunsCLVa1ouLMNMWaYbk5iywiVFoD9sz8djeZ2AtB8YHWLd0ovVNymd6/ h5xce/50G5Ski1+CiKGkWfTb49L640z7QD41zKjaekInLNhrnv1bIR8bQGSc2gPA8AcS fFzxdoVZnsamxxzMvkbuSAVUkj34UJj19tp4IgjMye2E3J5d4TDv7keWpVrxeYSQ9Q+8 W8Uw1H9eFwO9epxkSyzbTQZwtw2VOMEtd7GDl4kOcoSLN5r/MEwKjaNiRfZqaEuUPsB3 +BEg== X-Gm-Message-State: ANoB5pm77EgsR2DeaFcOGIkvZSvA6VIiWe2d08Nj/ByHQTRmodQ40eKb 5A3A4EREAfC2DGouAz+Mw1t3yEsFPU6v2bWurQc= X-Google-Smtp-Source: AA0mqf4T6ueRsRNqzZaOma/aLCP++R3nnmia9P5G7T6dqeJPa7vH1dfUCHCx5tQ1suk/1zxiU7PNGL1XYHTd+rmPxo8= X-Received: by 2002:a17:907:9096:b0:7c0:e306:8930 with SMTP id ge22-20020a170907909600b007c0e3068930mr18573311ejb.386.1670973203977; Tue, 13 Dec 2022 15:13:23 -0800 (PST) MIME-Version: 1.0 References: <4366aeb5-7fdb-6fa4-b0f5-ebe74c1d4fb2@jguk.org> <68c69b5a-e6e7-7021-5f98-37ba8f3c49eb@jguk.org> In-Reply-To: From: Jonathan Wakely Date: Tue, 13 Dec 2022 23:13:12 +0000 Message-ID: Subject: Re: Avoiding stack buffer clear being optimised out To: Jonny Grant Cc: gcc-help Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-0.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,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 Tue, 13 Dec 2022 at 22:07, Jonny Grant wrote: > > > > On 13/12/2022 20:31, Jonathan Wakely wrote: > > > > > > On Tue, 13 Dec 2022, 20:12 Jonny Grant, > wrote: > > > > > > > > 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 ju= st tips how to compile code. I only want to discuss this optimiser issue :-= ) > > >> > > >> https://blog.cloudflare.com/the-linux-kernel-key-retention-servi= ce-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 addin= g another printf, (propagating a return code after checking memset wasn't e= nough) > > > > > > This is simpler and works for me, but I'm not sure if it's guaran= teed > > > to always work: > > > > > > __attribute__((noinline,noipa)) > > > void wipe(void* p, size_t n) > > > { > > > memset(p, 0, n); > > > } > > > > > > static int encrypt(void) > > > { > > > uint8_t key[] =3D "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 f= ollowing example, the memset even changes the bytes on the stack, which are= then not changed later on in the program, rather strange. > > > > > > No it doesn't. > > > > The observable behaviour of the function is to write zero to several by= tes, then check if one of them was zero. The compiler doesn't need to write= anything or read anything to produce that behaviour, the read can never *n= ot* read a zero there, so the compiler doesn't bother to write anything *or= * read anything. It optimizes the whole function to simply: > > > > puts("encrypting with super secret key: hunter2"); > > return 0; > > ok, that is what I thought, it seems to know how the internals of memset(= ) work. Maybe because it's a builtin? It doesn't need to know anything about the internals, only the observable behaviour, which is entirely defined by the C standard. > > > > > If I modify the code to check the buffer contains key[0] as nul byt= e, it still shows as 0, > > > > > > You asked whether something just set to zero is equal to zero. That's r= edundant, of course it is. There is no need to waste CPU cycles on that. > > That makes sense. So if I wrote a assembler implementation I called memse= t_asm() I imagine gcc wouldn't be able to understand that it set those byte= s to zero? so it wouldn't remove my memset_asm() call. > > Regards, Jonny