From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qv1-xf42.google.com (mail-qv1-xf42.google.com [IPv6:2607:f8b0:4864:20::f42]) by sourceware.org (Postfix) with ESMTPS id E046F3860017 for ; Mon, 26 Oct 2020 19:46:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E046F3860017 Received: by mail-qv1-xf42.google.com with SMTP id g13so4912502qvu.1 for ; Mon, 26 Oct 2020 12:46:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:references:autocrypt :message-id:date:user-agent:mime-version:in-reply-to :content-language:content-transfer-encoding; bh=QH1t6apSt2ax3Fcehac+ab1QSFcQ84/0Avat0uVScwQ=; b=CBLgB0YhOnKOETQnd4HQPd6icYcmo0Sfg67vVpBaFoOGKNor+WcDGate8fjszLr5gF C/72+24VL9v5whITCju/ky9M4XIt0DraXLijXI7EWKKL4RB0gbXu6eNIn9c4DucQw7rU UNt+/oA6zwMTZqGjVydpYMjN0mUxG0oMsDd2H01uBCKQRac6s3tavRVZ8FJyg7yF4U5O zWqFPSOkWqDZrsD0Fs+eylb3saL2uwk/jfYboxyN7CWupyNoo7IfM/nE5M1UYRMEkZji 0ET4d90aw/N1LElDksaRDy0O4BEnwCbJiokIYOiTNkbi1B5+lXFynamWhQtj8eyob+P0 BmZg== X-Gm-Message-State: AOAM531xY0FHWfjrXiviNr+34B+L4TZvElZ3+528wOVPnm6xYHjoAO4H mp8Zb0LHZELdxtXYhN8H/1itsH8NdjLwtQ== X-Google-Smtp-Source: ABdhPJyg2SaZdSAJuVllmhgnoj5Az+CA3aXZry6hBo7w51aY3nXhhZwcaOvpq/qO16Q6lANNcj2pcQ== X-Received: by 2002:ad4:4c4a:: with SMTP id cs10mr15894934qvb.48.1603741593233; Mon, 26 Oct 2020 12:46:33 -0700 (PDT) Received: from [192.168.1.4] ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id d10sm7235018qkl.73.2020.10.26.12.46.31 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 26 Oct 2020 12:46:32 -0700 (PDT) Subject: Re: [PATCH 1/2] posix: Sync tempname with gnulib [BZ #26648] From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Jakub Jelinek References: <20200929125546.3413273-1-adhemerval.zanella@linaro.org> Autocrypt: addr=adhemerval.zanella@linaro.org; prefer-encrypt=mutual; keydata= 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 Message-ID: <1d55fc8a-4cc5-a88d-e3b8-b7439cbaa017@linaro.org> Date: Mon, 26 Oct 2020 16:46:30 -0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: <20200929125546.3413273-1-adhemerval.zanella@linaro.org> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-15.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, NICE_REPLY_A, 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-List-Received-Date: Mon, 26 Oct 2020 19:46:36 -0000 Ping. On 29/09/2020 09:55, Adhemerval Zanella wrote: > It syncs with commit 6160ee8e4d2b88d934c3c4c8c5930a75b835723f. It > now uses getrandom on each iteration to get entropy and only uses > the clock as source of entropy if getrandom fails. > > Checked on x86_64-linux-gnu. > --- > sysdeps/posix/tempname.c | 280 +++++++++++++++++++++++---------------- > 1 file changed, 163 insertions(+), 117 deletions(-) > > diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c > index 1864c860ad..03426c23cf 100644 > --- a/sysdeps/posix/tempname.c > +++ b/sysdeps/posix/tempname.c > @@ -16,7 +16,7 @@ > . */ > > #if !_LIBC > -# include > +# include > # include "tempname.h" > #endif > > @@ -24,9 +24,6 @@ > #include > > #include > -#ifndef __set_errno > -# define __set_errno(Val) errno = (Val) > -#endif > > #include > #ifndef P_tmpdir > @@ -36,12 +33,12 @@ > # define TMP_MAX 238328 > #endif > #ifndef __GT_FILE > -# define __GT_FILE 0 > -# define __GT_DIR 1 > -# define __GT_NOCREATE 2 > +# define __GT_FILE 0 > +# define __GT_DIR 1 > +# define __GT_NOCREATE 2 > #endif > -#if !_LIBC && (GT_FILE != __GT_FILE || GT_DIR != __GT_DIR \ > - || GT_NOCREATE != __GT_NOCREATE) > +#if !_LIBC && (GT_FILE != __GT_FILE || GT_DIR != __GT_DIR \ > + || GT_NOCREATE != __GT_NOCREATE) > # error report this to bug-gnulib@gnu.org > #endif > > @@ -50,11 +47,11 @@ > #include > > #include > -#include > +#include > #include > -#include > - > +#include > #include > +#include > > #if _LIBC > # define struct_stat64 struct stat64 > @@ -62,32 +59,36 @@ > #else > # define struct_stat64 struct stat > # define __gen_tempname gen_tempname > -# define __getpid getpid > # define __mkdir mkdir > # define __open open > -# define __secure_getenv secure_getenv > +# define __lxstat64(version, file, buf) lstat (file, buf) > +# define __getrandom getrandom > +# define __clock_gettime64 clock_gettime > +# define __timespec64 timespec > #endif > > -#ifdef _LIBC > -# include > -# define RANDOM_BITS(Var) ((Var) = random_bits ()) > -# else > -# define RANDOM_BITS(Var) \ > - { \ > - struct timespec ts; \ > - clock_gettime (CLOCK_REALTIME, &ts); \ > - (Var) = ((uint64_t) tv.tv_nsec << 16) ^ tv.tv_sec; \ > - } > -#endif > +/* Use getrandom if it works, falling back on a 64-bit linear > + congruential generator that starts with Var's value > + mixed in with a clock's low-order bits if available. */ > +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) > > -/* Use the widest available unsigned type if uint64_t is not > - available. The algorithm below extracts a number less than 62**6 > - (approximately 2**35.725) from uint64_t, so ancient hosts where > - uintmax_t is only 32 bits lose about 3.725 bits of randomness, > - which is better than not having mkstemp at all. */ > -#if !defined UINT64_MAX && !defined uint64_t > -# define uint64_t uintmax_t > +static random_value > +random_bits (random_value var) > +{ > + random_value r; > + if (__getrandom (&r, sizeof r, 0) == sizeof r) > + return r; > +#if _LIBC || (defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME) > + /* Add entropy if getrandom is not supported. */ > + struct __timespec64 tv; > + __clock_gettime64 (CLOCK_MONOTONIC, &tv); > + var ^= tv.tv_nsec; > #endif > + return 2862933555777941757 * var + 3037000493; > +} > > #if _LIBC > /* Return nonzero if DIR is an existent directory. */ > @@ -95,7 +96,7 @@ static int > direxists (const char *dir) > { > struct_stat64 buf; > - return __stat64 (dir, &buf) == 0 && S_ISDIR (buf.st_mode); > + return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode); > } > > /* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is > @@ -106,7 +107,7 @@ direxists (const char *dir) > enough space in TMPL. */ > int > __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, > - int try_tmpdir) > + int try_tmpdir) > { > const char *d; > size_t dlen, plen; > @@ -120,35 +121,35 @@ __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, > { > plen = strlen (pfx); > if (plen > 5) > - plen = 5; > + plen = 5; > } > > if (try_tmpdir) > { > d = __secure_getenv ("TMPDIR"); > if (d != NULL && direxists (d)) > - dir = d; > + dir = d; > else if (dir != NULL && direxists (dir)) > - /* nothing */ ; > + /* nothing */ ; > else > - dir = NULL; > + dir = NULL; > } > if (dir == NULL) > { > if (direxists (P_tmpdir)) > - dir = P_tmpdir; > + dir = P_tmpdir; > else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp")) > - dir = "/tmp"; > + dir = "/tmp"; > else > - { > - __set_errno (ENOENT); > - return -1; > - } > + { > + __set_errno (ENOENT); > + return -1; > + } > } > > dlen = strlen (dir); > while (dlen > 1 && dir[dlen - 1] == '/') > - dlen--; /* remove trailing slashes */ > + dlen--; /* remove trailing slashes */ > > /* check we have room for "${dir}/${pfx}XXXXXX\0" */ > if (tmpl_len < dlen + 1 + plen + 6 + 1) > @@ -162,39 +163,91 @@ __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, > } > #endif /* _LIBC */ > > +#if _LIBC > +static int try_tempname_len (char *, int, void *, int (*) (char *, void *), > + size_t); > +#endif > + > +static int > +try_file (char *tmpl, void *flags) > +{ > + int *openflags = flags; > + return __open (tmpl, > + (*openflags & ~O_ACCMODE) > + | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); > +} > + > +static int > +try_dir (char *tmpl, void *flags _GL_UNUSED) > +{ > + return __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); > +} > + > +static int > +try_nocreate (char *tmpl, void *flags _GL_UNUSED) > +{ > + struct_stat64 st; > + > + if (__lxstat64 (_STAT_VER, tmpl, &st) == 0 || errno == EOVERFLOW) > + __set_errno (EEXIST); > + return errno == ENOENT ? 0 : -1; > +} > + > /* These are the characters used in temporary file names. */ > static const char letters[] = > "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; > > /* Generate a temporary file name based on TMPL. TMPL must match the > - rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix). > + rules for mk[s]temp (i.e., end in at least X_SUFFIX_LEN "X"s, > + possibly with a suffix). > The name constructed does not exist at the time of the call to > - __gen_tempname. TMPL is overwritten with the result. > + this function. TMPL is overwritten with the result. > > KIND may be one of: > - __GT_NOCREATE: simply verify that the name does not exist > - at the time of the call. > - __GT_FILE: create the file using open(O_CREAT|O_EXCL) > - and return a read-write fd. The file is mode 0600. > - __GT_DIR: create a directory, which will be mode 0700. > + __GT_NOCREATE: simply verify that the name does not exist > + at the time of the call. > + __GT_FILE: create the file using open(O_CREAT|O_EXCL) > + and return a read-write fd. The file is mode 0600. > + __GT_DIR: create a directory, which will be mode 0700. > > We use a clever algorithm to get hard-to-predict names. */ > +#ifdef _LIBC > +static > +#endif > int > -__gen_tempname (char *tmpl, int suffixlen, int flags, int kind) > +gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind, > + size_t x_suffix_len) > { > - int len; > + static int (*const tryfunc[]) (char *, void *) = > + { > + [__GT_FILE] = try_file, > + [__GT_DIR] = try_dir, > + [__GT_NOCREATE] = try_nocreate > + }; > + return try_tempname_len (tmpl, suffixlen, &flags, tryfunc[kind], > + x_suffix_len); > +} > + > +#ifdef _LIBC > +static > +#endif > +int > +try_tempname_len (char *tmpl, int suffixlen, void *args, > + int (*tryfunc) (char *, void *), size_t x_suffix_len) > +{ > + size_t len; > char *XXXXXX; > unsigned int count; > int fd = -1; > int save_errno = errno; > - struct_stat64 st; > > /* A lower bound on the number of temporary files to attempt to > generate. The maximum total number of temporary file names that > can exist for a given template is 62**6. It should never be > necessary to try all of these combinations. Instead if a reasonable > number of names is tried (we define reasonable as 62**3) fail to > - give the system administrator the chance to remove the problems. */ > + give the system administrator the chance to remove the problems. > + This value requires that X_SUFFIX_LEN be at least 3. */ > #define ATTEMPTS_MIN (62 * 62 * 62) > > /* The number of times to attempt to generate a temporary file. To > @@ -205,82 +258,75 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind) > unsigned int attempts = ATTEMPTS_MIN; > #endif > > + /* 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) / alignof (max_align_t); > + > + /* How many random base-62 digits can currently be extracted from V. */ > + int vdigits = 0; > + > + /* Least unfair value for V. If V is less than this, V can generate > + BASE_62_DIGITS digits fairly. Otherwise it might be biased. */ > + random_value const unfair_min > + = RANDOM_VALUE_MAX - RANDOM_VALUE_MAX % BASE_62_POWER; > + > len = strlen (tmpl); > - if (len < 6 + suffixlen || memcmp (&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) > + if (len < x_suffix_len + suffixlen > + || strspn (&tmpl[len - x_suffix_len - suffixlen], "X") < x_suffix_len) > { > __set_errno (EINVAL); > return -1; > } > > /* This is where the Xs start. */ > - XXXXXX = &tmpl[len - 6 - suffixlen]; > + XXXXXX = &tmpl[len - x_suffix_len - suffixlen]; > > - uint64_t pid = (uint64_t) __getpid () << 32; > for (count = 0; count < attempts; ++count) > { > - uint64_t v; > - /* Get some more or less random data. */ > - RANDOM_BITS (v); > - v ^= pid; > - > - /* Fill in the random bits. */ > - XXXXXX[0] = letters[v % 62]; > - v /= 62; > - XXXXXX[1] = letters[v % 62]; > - v /= 62; > - XXXXXX[2] = letters[v % 62]; > - v /= 62; > - XXXXXX[3] = letters[v % 62]; > - v /= 62; > - XXXXXX[4] = letters[v % 62]; > - v /= 62; > - XXXXXX[5] = letters[v % 62]; > - > - switch (kind) > - { > - case __GT_FILE: > - fd = __open (tmpl, > - (flags & ~O_ACCMODE) > - | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); > - break; > - > - case __GT_DIR: > - fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); > - break; > - > - case __GT_NOCREATE: > - /* This case is backward from the other three. __gen_tempname > - succeeds if lstat fails because the name does not exist. > - Note the continue to bypass the common logic at the bottom > - of the loop. */ > - if (__lstat64 (tmpl, &st) < 0) > - { > - if (errno == ENOENT) > - { > - __set_errno (save_errno); > - return 0; > - } > - else > - /* Give up now. */ > - return -1; > - } > - continue; > - > - default: > - assert (! "invalid KIND in __gen_tempname"); > - abort (); > - } > - > + for (size_t i = 0; i < x_suffix_len; i++) > + { > + if (vdigits == 0) > + { > + do > + v = random_bits (v); > + while (unfair_min <= v); > + > + vdigits = BASE_62_DIGITS; > + } > + > + XXXXXX[i] = letters[v % 62]; > + v /= 62; > + vdigits--; > + } > + > + fd = tryfunc (tmpl, args); > if (fd >= 0) > - { > - __set_errno (save_errno); > - return fd; > - } > + { > + __set_errno (save_errno); > + return fd; > + } > else if (errno != EEXIST) > - return -1; > + return -1; > } > > /* We got out of the loop because we ran out of combinations to try. */ > __set_errno (EEXIST); > return -1; > } > + > +int > +__gen_tempname (char *tmpl, int suffixlen, int flags, int kind) > +{ > + return gen_tempname_len (tmpl, suffixlen, flags, kind, 6); > +} > + > +#if !_LIBC > +int > +try_tempname (char *tmpl, int suffixlen, void *args, > + int (*tryfunc) (char *, void *)) > +{ > + return try_tempname_len (tmpl, suffixlen, args, tryfunc, 6); > +} > +#endif >