From patchwork Wed Sep 9 17:53:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 40389 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CB5553860C35; Wed, 9 Sep 2020 17:54:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CB5553860C35 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1599674045; bh=JhVtb4kHtmqWGY9ers4QgwGLImiZRuYKSsKD1MFCMCI=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=JoDjLgsjses7U4x+XyPOYIYYxYEOKv1g/UW72bjBihwCMvyQcG7nJX0q39pp2QN9U lToqhyymjJ6M/lzUPSHp5y6totYQH5RfsyRvmoxyhsgZ5O0iLRwgN2IBM8pGGKYVg8 u7ZHoAXdrpSZeEWKGwcsV2YiYEOraohTl+L3LGkQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x732.google.com (mail-qk1-x732.google.com [IPv6:2607:f8b0:4864:20::732]) by sourceware.org (Postfix) with ESMTPS id 35470385782B for ; Wed, 9 Sep 2020 17:54:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 35470385782B Received: by mail-qk1-x732.google.com with SMTP id v123so3258740qkd.9 for ; Wed, 09 Sep 2020 10:54:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JhVtb4kHtmqWGY9ers4QgwGLImiZRuYKSsKD1MFCMCI=; b=Z7AHdhEDXYJfGBSsha0346gEu+dALquD/IEtbERWTc1CHxersBKXQB+9m2DOmNa7n9 b5dzmKCdKSGtL4uc09qnJHSK/0ryxF7iEjHORB1tLE2Fadsid2/KJUrg0FqY0Yevhuq2 rVY4XEZ+WW47nOvbcmAyNc/YR+NQd2/5AK3ls1at60canF//qSQHiOEAKS4VKPO/BM5A gB4CH/AJfyo8z9N485eJh5Vz3eKdPyjNOm/xhR0Fo20acdjcjbWVtusN0xthVyEPRZ3q 9RGR4gz3Eq4T2GPeL7e1yQudG/XrJEB7/5EutpIcBq4Z5nugz+hqR7wA00SniXKFj41D jolA== X-Gm-Message-State: AOAM533bMP7+E8vFDkKuFNngzVjOE6xUcj6JKBx0NyQHbPkzbmjkxb/u 69qeaQ+4mZDt23QYeONnLVzQcuXwDOX+wQ== X-Google-Smtp-Source: ABdhPJwTtZaHR6aVvIyxBnhaZwwunmWqewoIdWM4Hp7gbb7faqvnYok5/HANKEILC/0XYT4GBovySQ== X-Received: by 2002:a05:620a:101a:: with SMTP id z26mr4336307qkj.300.1599674042454; Wed, 09 Sep 2020 10:54:02 -0700 (PDT) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id x126sm3509639qka.91.2020.09.09.10.54.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 10:54:02 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH 2/2] Use getrandom on try_tempname_len [BZ #15813] Date: Wed, 9 Sep 2020 14:53:55 -0300 Message-Id: <20200909175355.2594189-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200909175355.2594189-1-adhemerval.zanella@linaro.org> References: <20200909175355.2594189-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: Jakub Jelinek Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" Remove the usage of random-bits.h for _LIBC and use getrandom instead. Also, the fallback relies on UB (the LCG might use unitialized value from the stack variable) so initialize the initial state using some ASLR entropy. The fallback will be always used on Linux with kernels older than 3.17, so it also adds some extra entropy based on the clock for the linear congruential generator (LCG). Checked on x86_64-linux-gnu. --- sysdeps/posix/tempname.c | 41 +++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c index 9219ee66af..1ef5536814 100644 --- a/sysdeps/posix/tempname.c +++ b/sysdeps/posix/tempname.c @@ -60,27 +60,31 @@ # define __mkdir mkdir # define __open open # define __lxstat64(version, file, buf) lstat (file, buf) +# define __getrandom getrandom #endif -#ifdef _LIBC -# include -# define RANDOM_BITS(Var) ((Var) = random_bits ()) -typedef uint32_t random_value; -# define RANDOM_VALUE_MAX UINT32_MAX -# define BASE_62_DIGITS 5 /* 62**5 < UINT32_MAX */ -# define BASE_62_POWER (62 * 62 * 62 * 62 * 62) /* 2**BASE_62_DIGITS */ -#else /* Use getrandom if it works, falling back on a 64-bit linear congruential generator that starts with whatever Var's value happens to be. */ -# define RANDOM_BITS(Var) \ - ((void) (getrandom (&(Var), sizeof (Var), 0) == sizeof (Var) \ - || ((Var) = 2862933555777941757 * (Var) + 3037000493))) typedef uint_fast64_t random_value; -# define RANDOM_VALUE_MAX UINT_FAST64_MAX -# define BASE_62_DIGITS 10 /* 62**10 < UINT_FAST64_MAX */ -# define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62) +#define RANDOM_VALUE_MAX UINT_FAST64_MAX +#define BASE_62_DIGITS 10 /* 62**10 < UINT_FAST64_MAX */ +#define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62) + +static random_value +random_bits (random_value var) +{ + random_value r; + if (__getrandom (&r, sizeof (r), 0) == sizeof (r)) + return r; +#if _LIBC + /* Add some more entropy if getrandom is not supported. */ + struct __timespec64 tv; + __clock_gettime64 (CLOCK_MONOTONIC, &tv); + var = var ^ tv.tv_nsec; #endif + return 2862933555777941757 * var + 3037000493; +} #if _LIBC /* Return nonzero if DIR is an existent directory. */ @@ -250,8 +254,11 @@ try_tempname_len (char *tmpl, int suffixlen, void *args, unsigned int attempts = ATTEMPTS_MIN; #endif - /* A random variable. */ - random_value v; + /* A random variable. The initial value is used only the for fallback path + on 'random_bits' on 'getrandom' failure. Its initial value tries to use + some entropy from the ASLR and ignore possible bits from the stack + alignment. */ + random_value v = ((uintptr_t) &v) / 16; /* How many random base-62 digits can currently be extracted from V. */ int vdigits = 0; @@ -279,7 +286,7 @@ try_tempname_len (char *tmpl, int suffixlen, void *args, if (vdigits == 0) { do - RANDOM_BITS (v); + v = random_bits (v); while (unfair_min <= v); vdigits = BASE_62_DIGITS;