From owner-svn-src-all@freebsd.org Tue Sep 3 14:07:26 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id A952FDCD92; Tue, 3 Sep 2019 14:06:40 +0000 (UTC) (envelope-from yuripv@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2610:1c1:1:6074::16:84]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "freefall.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46N7zg5ZNqz4PnG; Tue, 3 Sep 2019 14:06:39 +0000 (UTC) (envelope-from yuripv@freebsd.org) Received: by freefall.freebsd.org (Postfix, from userid 1452) id 161AF1A9C9; Tue, 3 Sep 2019 14:06:14 +0000 (UTC) X-Original-To: yuripv@localmail.freebsd.org Delivered-To: yuripv@localmail.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client CN "mx1.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by freefall.freebsd.org (Postfix) with ESMTPS id EC6C51E872; Thu, 11 Apr 2019 05:08:53 +0000 (UTC) (envelope-from owner-src-committers@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2610:1c1:1:6074::16:84]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "freefall.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 3623F75DC1; Thu, 11 Apr 2019 05:08:53 +0000 (UTC) (envelope-from owner-src-committers@freebsd.org) Received: by freefall.freebsd.org (Postfix, from userid 538) id 0E2521E80C; Thu, 11 Apr 2019 05:08:53 +0000 (UTC) Delivered-To: src-committers@localmail.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client CN "mx1.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by freefall.freebsd.org (Postfix) with ESMTPS id 8ED591E807 for ; Thu, 11 Apr 2019 05:08:50 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 434DE75DBB; Thu, 11 Apr 2019 05:08:50 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 290985725; Thu, 11 Apr 2019 05:08:50 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x3B58n2T023792; Thu, 11 Apr 2019 05:08:49 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x3B58nFT023791; Thu, 11 Apr 2019 05:08:49 GMT (envelope-from cem@FreeBSD.org) Message-Id: <201904110508.x3B58nFT023791@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: Conrad Meyer To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r346116 - head/usr.bin/sort X-SVN-Group: head X-SVN-Commit-Author: cem X-SVN-Commit-Paths: head/usr.bin/sort X-SVN-Commit-Revision: 346116 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk X-Loop: FreeBSD.org Sender: owner-src-committers@freebsd.org X-Rspamd-Queue-Id: 3623F75DC1 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.97 / 15.00]; local_wl_from(0.00)[freebsd.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.998,0]; NEURAL_HAM_SHORT(-0.97)[-0.973,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-1.000,0] Status: O X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Date: Tue, 03 Sep 2019 14:07:26 -0000 X-Original-Date: Thu, 11 Apr 2019 05:08:49 +0000 (UTC) X-List-Received-Date: Tue, 03 Sep 2019 14:07:26 -0000 Author: cem Date: Thu Apr 11 05:08:49 2019 New Revision: 346116 URL: https://svnweb.freebsd.org/changeset/base/346116 Log: sort(1): Simplify and bound random seeding Bound input file processing length to avoid the issue reported in [1]. For simplicity, only allow regular file and character device inputs. For character devices, only allow /dev/random (and /dev/urandom symblink). 32 bytes of random is perfectly sufficient to seed MD5; we don't need any more. Users that want to use large files as seeds are encouraged to truncate those files down to an appropriate input file via tools like sha256(1). (This does not change the sort algorithm of sort -R.) [1]: https://lists.freebsd.org/pipermail/freebsd-hackers/2018-August/053152.html PR: 230792 Reported by: Ali Abdallah Relnotes: yes Modified: head/usr.bin/sort/sort.c Modified: head/usr.bin/sort/sort.c ============================================================================== --- head/usr.bin/sort/sort.c Thu Apr 11 04:24:41 2019 (r346115) +++ head/usr.bin/sort/sort.c Thu Apr 11 05:08:49 2019 (r346116) @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -61,13 +62,7 @@ nl_catd catalog; #define OPTIONS "bcCdfghik:Mmno:RrsS:t:T:uVz" -#define DEFAULT_RANDOM_SORT_SEED_FILE ("/dev/random") -#define MAX_DEFAULT_RANDOM_SEED_DATA_SIZE (1024) - static bool need_random; -static const char *random_source = DEFAULT_RANDOM_SORT_SEED_FILE; -static const void *random_seed; -static size_t random_seed_size; MD5_CTX md5_ctx; @@ -907,55 +902,76 @@ fix_obsolete_keys(int *argc, char **argv) } /* - * Set random seed + * Seed random sort */ static void -set_random_seed(void) +get_random_seed(const char *random_source) { - if (strcmp(random_source, DEFAULT_RANDOM_SORT_SEED_FILE) == 0) { - FILE* fseed; - MD5_CTX ctx; - char rsd[MAX_DEFAULT_RANDOM_SEED_DATA_SIZE]; - size_t sz = 0; + char randseed[32]; + struct stat fsb, rsb; + ssize_t rd; + int rsfd; - fseed = openfile(random_source, "r"); - while (!feof(fseed)) { - int cr; + rsfd = -1; + rd = sizeof(randseed); - cr = fgetc(fseed); - if (cr == EOF) - break; + if (random_source == NULL) { + if (getentropy(randseed, sizeof(randseed)) < 0) + err(EX_SOFTWARE, "getentropy"); + goto out; + } - rsd[sz++] = (char) cr; + rsfd = open(random_source, O_RDONLY | O_CLOEXEC); + if (rsfd < 0) + err(EX_NOINPUT, "open: %s", random_source); - if (sz >= MAX_DEFAULT_RANDOM_SEED_DATA_SIZE) - break; - } + if (fstat(rsfd, &fsb) != 0) + err(EX_SOFTWARE, "fstat"); - closefile(fseed, random_source); + if (!S_ISREG(fsb.st_mode) && !S_ISCHR(fsb.st_mode)) + err(EX_USAGE, + "random seed isn't a regular file or /dev/random"); - MD5Init(&ctx); - MD5Update(&ctx, rsd, sz); + /* + * Regular files: read up to maximum seed size and explicitly + * reject longer files. + */ + if (S_ISREG(fsb.st_mode)) { + if (fsb.st_size > (off_t)sizeof(randseed)) + errx(EX_USAGE, "random seed is too large (%jd >" + " %zu)!", (intmax_t)fsb.st_size, + sizeof(randseed)); + else if (fsb.st_size < 1) + errx(EX_USAGE, "random seed is too small (" + "0 bytes)"); - random_seed = MD5End(&ctx, NULL); - random_seed_size = strlen(random_seed); + memset(randseed, 0, sizeof(randseed)); - } else { - MD5_CTX ctx; - char *b; + rd = read(rsfd, randseed, fsb.st_size); + if (rd < 0) + err(EX_SOFTWARE, "reading random seed file %s", + random_source); + if (rd < (ssize_t)fsb.st_size) + errx(EX_SOFTWARE, "short read from %s", random_source); + } else if (S_ISCHR(fsb.st_mode)) { + if (stat("/dev/random", &rsb) < 0) + err(EX_SOFTWARE, "stat"); - MD5Init(&ctx); - b = MD5File(random_source, NULL); - if (b == NULL) - err(2, NULL); + if (fsb.st_dev != rsb.st_dev || + fsb.st_ino != rsb.st_ino) + errx(EX_USAGE, "random seed is a character " + "device other than /dev/random"); - random_seed = b; - random_seed_size = strlen(b); + if (getentropy(randseed, sizeof(randseed)) < 0) + err(EX_SOFTWARE, "getentropy"); } + +out: + if (rsfd >= 0) + close(rsfd); + MD5Init(&md5_ctx); - if(random_seed_size>0) { - MD5Update(&md5_ctx, random_seed, random_seed_size); - } + MD5Update(&md5_ctx, randseed, rd); } /* @@ -965,6 +981,7 @@ int main(int argc, char **argv) { char *outfile, *real_outfile; + char *random_source = NULL; int c, result; bool mef_flags[NUMBER_OF_MUTUALLY_EXCLUSIVE_FLAGS] = { false, false, false, false, false, false }; @@ -1225,7 +1242,7 @@ main(int argc, char **argv) } if (need_random) - set_random_seed(); + get_random_seed(random_source); /* Case when the outfile equals one of the input files: */ if (strcmp(outfile, "-")) {