diff mbox series

[BUG] Git 2.48.0-rc2 - Test t0610.26 Fails

Message ID 002c01db60a5$7a367060$6ea35120$@nexbridge.com (mailing list archive)
State New
Headers show
Series [BUG] Git 2.48.0-rc2 - Test t0610.26 Fails | expand

Commit Message

Randall S. Becker Jan. 7, 2025, 1:42 a.m. UTC
The following breaks at rc2. It worked correctly at rc1 on x86 but
apparently not on ia64.

The OpenSSL random generator on ia64 uses PRNGD. On x86, the hardware
randomizer
is used. Nonetheless, this is not working properly:

expecting success of 0610.47 'ref transaction: many concurrent writers':
        test_when_finished "rm -rf repo" &&
        git init repo &&
        (
                cd repo &&
                # Set a high timeout. While a couple of seconds should be
                # plenty, using the address sanitizer will significantly
slow
                # us down here. So we are aiming way higher than you would
ever
                # think is necessary just to keep us from flaking. We could
                # also lock indefinitely by passing -1, but that could
                # potentially block CI jobs indefinitely if there was a bug
                # here.
                git config set reftable.lockTimeout 300000 &&
                test_commit --no-tag initial &&

                head=$(git rev-parse HEAD) &&
                for i in $(test_seq 100)
                do
                        printf "%s commit\trefs/heads/branch-%s\n" "$head"
"$i" ||
                        return 1
                done >expect &&
                printf "%s commit\trefs/heads/main\n" "$head" >>expect &&

                for i in $(test_seq 100)
                do
                        { git update-ref refs/heads/branch-$i HEAD& } ||
                        return 1
                done &&

                wait &&
                git for-each-ref --sort=v:refname >actual &&
                test_cmp expect actual
        )

+ test_when_finished rm -rf repo
+ git init repo
Initialized empty Git repository in
/home/ituglib/randall/jenkins/.jenkins/workspace/Git_Pipeline/t/trash
directory.t0610-reftable-basics/repo/.git/
+ cd repo
+ git config set reftable.lockTimeout 300000
+ test_commit --no-tag initial
[main (root-commit) 68d032e] initial
 Author: A U Thor <author@example.com>
 1 file changed, 1 insertion(+)
 create mode 100644 initial.t
+ + git rev-parse HEAD
head=68d032e9edd3481ac96382786ececc37ec28709e
+ 1> expect
+ test_seq 100
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 1
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 2
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 3
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 4
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 5
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 6
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 7
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 8
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 9
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 10
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 11
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 12
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 13
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 14
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 15
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 16
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 17
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 18
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 19
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 20
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 21
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 22
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 23
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 24
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 25
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 26
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 27
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 28
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 29
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 30
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 31
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 32
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 33
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 34
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 35
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 36
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 37
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 38
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 39
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 40
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 41
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 42
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 43
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 44
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 45
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 46
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 47
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 48
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 49
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 50
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 51
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 52
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 53
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 54
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 55
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 56
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 57
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 58
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 59
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 60
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 61
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 62
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 63
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 64
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 65
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 66
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 67
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 68
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 69
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 70
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 71
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 72
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 73
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 74
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 75
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 76
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 77
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 78
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 79
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 80
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 81
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 82
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 83
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 84
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 85
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 86
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 87
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 88
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 89
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 90
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 91
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 92
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 93
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 94
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 95
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 96
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 97
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 98
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 99
+ printf %s commit\trefs/heads/branch-%s\n
68d032e9edd3481ac96382786ececc37ec28709e 100
+ printf %s commit\trefs/heads/main\n
68d032e9edd3481ac96382786ececc37ec28709e
+ 1>> expect
+ test_seq 100
+ git update-ref refs/heads/branch-1 HEAD
+ git update-ref refs/heads/branch-2 HEAD
+ git update-ref refs/heads/branch-7 HEAD
+ git update-ref refs/heads/branch-3 HEAD
+ git update-ref refs/heads/branch-5 HEAD
+ git update-ref refs/heads/branch-6 HEAD
+ git update-ref refs/heads/branch-4 HEAD
+ git update-ref refs/heads/branch-8 HEAD
+ git update-ref refs/heads/branch-9 HEAD
+ git update-ref refs/heads/branch-10 HEAD
+ git update-ref refs/heads/branch-11 HEAD
+ git update-ref refs/heads/branch-12 HEAD
+ git update-ref refs/heads/branch-13 HEAD
+ git update-ref refs/heads/branch-14 HEAD
+ git update-ref refs/heads/branch-15 HEAD
+ git update-ref refs/heads/branch-16 HEAD
+ git update-ref refs/heads/branch-17 HEAD
+ git update-ref refs/heads/branch-18 HEAD
+ git update-ref refs/heads/branch-19 HEAD
+ git update-ref refs/heads/branch-20 HEAD
+ git update-ref refs/heads/branch-21 HEAD
+ git update-ref refs/heads/branch-22 HEAD
+ git update-ref refs/heads/branch-23 HEAD
+ git update-ref refs/heads/branch-24 HEAD
+ git update-ref refs/heads/branch-25 HEAD
+ git update-ref refs/heads/branch-26 HEAD
+ git update-ref refs/heads/branch-27 HEAD
+ git update-ref refs/heads/branch-28 HEAD
+ git update-ref refs/heads/branch-29 HEAD
+ git update-ref refs/heads/branch-31 HEAD
+ git update-ref refs/heads/branch-30 HEAD
+ git update-ref refs/heads/branch-34 HEAD
+ git update-ref refs/heads/branch-37 HEAD
+ git update-ref refs/heads/branch-38 HEAD
+ git update-ref refs/heads/branch-35 HEAD
+ git update-ref refs/heads/branch-36 HEAD
+ git update-ref refs/heads/branch-39 HEAD
+ git update-ref refs/heads/branch-40 HEAD
+ git update-ref refs/heads/branch-41 HEAD
+ git update-ref refs/heads/branch-32 HEAD
+ git update-ref refs/heads/branch-42 HEAD
+ git update-ref refs/heads/branch-33 HEAD
+ git update-ref refs/heads/branch-43 HEAD
+ git update-ref refs/heads/branch-44 HEAD
+ git update-ref refs/heads/branch-45 HEAD
+ git update-ref refs/heads/branch-46 HEAD
+ git update-ref refs/heads/branch-47 HEAD
+ git update-ref refs/heads/branch-48 HEAD
+ git update-ref refs/heads/branch-49 HEAD
+ git update-ref refs/heads/branch-52 HEAD
+ git update-ref refs/heads/branch-50 HEAD
+ git update-ref refs/heads/branch-51 HEAD
+ git update-ref refs/heads/branch-53 HEAD
+ git update-ref refs/heads/branch-56 HEAD
+ git update-ref refs/heads/branch-58 HEAD
+ git update-ref refs/heads/branch-61 HEAD
+ git update-ref refs/heads/branch-64 HEAD
+ git update-ref refs/heads/branch-55 HEAD
+ git update-ref refs/heads/branch-67 HEAD
+ git update-ref refs/heads/branch-59 HEAD
+ git update-ref refs/heads/branch-69 HEAD
+ git update-ref refs/heads/branch-63 HEAD
+ git update-ref refs/heads/branch-65 HEAD
+ git update-ref refs/heads/branch-68 HEAD
+ git update-ref refs/heads/branch-62 HEAD
+ git update-ref refs/heads/branch-60 HEAD
+ git update-ref refs/heads/branch-66 HEAD
+ git update-ref refs/heads/branch-54 HEAD
+ git update-ref refs/heads/branch-57 HEAD
+ git update-ref refs/heads/branch-71 HEAD
+ git update-ref refs/heads/branch-70 HEAD
+ git update-ref refs/heads/branch-72 HEAD
+ git update-ref refs/heads/branch-74 HEAD
+ git update-ref refs/heads/branch-73 HEAD
+ git update-ref refs/heads/branch-75 HEAD
+ git update-ref refs/heads/branch-77 HEAD
+ git update-ref refs/heads/branch-78 HEAD
+ git update-ref refs/heads/branch-82 HEAD
+ git update-ref refs/heads/branch-81 HEAD
+ git update-ref refs/heads/branch-76 HEAD
+ git update-ref refs/heads/branch-80 HEAD
+ git update-ref refs/heads/branch-79 HEAD
+ git update-ref refs/heads/branch-83 HEAD
+ wait
+ git update-ref refs/heads/branch-84 HEAD
+ git update-ref refs/heads/branch-85 HEAD
+ git update-ref refs/heads/branch-88 HEAD
+ git update-ref refs/heads/branch-96 HEAD
+ git update-ref refs/heads/branch-92 HEAD
+ git update-ref refs/heads/branch-93 HEAD
+ git update-ref refs/heads/branch-89 HEAD
+ git update-ref refs/heads/branch-86 HEAD
+ git update-ref refs/heads/branch-94 HEAD
+ git update-ref refs/heads/branch-95 HEAD
+ git update-ref refs/heads/branch-87 HEAD
+ git update-ref refs/heads/branch-90 HEAD
+ git update-ref refs/heads/branch-91 HEAD
+ git update-ref refs/heads/branch-98 HEAD
+ git update-ref refs/heads/branch-97 HEAD
+ git update-ref refs/heads/branch-99 HEAD
+ git update-ref refs/heads/branch-100 HEAD
fatal: unable to get random bytes
fatal: unable to get random bytes
fatal: unable to get random bytes
fatal: unable to get random bytes
fatal: unable to get random bytes
fatal: unable to get random bytes
fatal: unable to get random bytes
+ git for-each-ref --sort=v:refname
+ 1> actual
+ test_cmp expect actual
refs/heads/branch-100
error: last command exited with $?=1
not ok 47 - ref transaction: many concurrent writers

Comments

Patrick Steinhardt Jan. 7, 2025, 6:51 a.m. UTC | #1
On Mon, Jan 06, 2025 at 08:42:51PM -0500, rsbecker@nexbridge.com wrote:
> The following breaks at rc2. It worked correctly at rc1 on x86 but
> apparently not on ia64.
> 
> The OpenSSL random generator on ia64 uses PRNGD. On x86, the hardware
> randomizer
> is used. Nonetheless, this is not working properly:
[snip]
> fatal: unable to get random bytes
> fatal: unable to get random bytes
> fatal: unable to get random bytes
> fatal: unable to get random bytes
> fatal: unable to get random bytes
> fatal: unable to get random bytes
> fatal: unable to get random bytes

This here is the underlying error. I cannot spot any single change in
v2.48.0-rc1..v2.48.0-rc2 that would cause a difference in how we compute
random bytes. Seeing that this is in the reftable library, the only
change that _could_ be related are the realloc followup-fixes, but that
could only be a sensible explanation in case we ever tried to populate a
reallocated buffer with N random bytes. We don't though, as there are
only two callsites where we compute random bytes:

  - `format_name()`

  - `reftable_stack_reload_maybe_reuse()`

In both cases we only want to have a single integer.

The latter callsite is somewhat curious because we don't call
`git_rand()`, but `rand()` directly. That wouldn't ever cause us to die,
so we know that it has to be `format_name()` that dies in `git_rand()`.

So yes, I doubt that this has been introduced with v2.48.0-rc2, and
rather assume that this is a flake that you just never hit before by
chance. Due to the many threads racing with one another, all of which
will repeatedly acquire random bytes, we probably end up exhausting the
pool of strong random entropy, and that makes OpenSSLs `RAND_bytes()`
fail.

It's somewhat sad that we die here, because it would be perfectly fine
to accept a pseudo-random number in our usecase. Using `rand()` does not
work work though because we never seed it, and I don't want to get into
that business, and thus it would return deterministic sequences of file
names for reftable stacks.

We _could_ adapt the code to use `RAND_pseudo_bytes()` for OpenSSL,
which never fails due to an exhausted entropy pool, but that'd first
require us to audit every callsite to figure out whether or not it needs
strong entropy. Another alternative would be to introduce a flag into
`csprng_bytes()` that tells it to also accept insecure bytes. That would
look something like the (not even compile-tested) diff at the end of
this mail.

Anyway. If my analysis is correct I don't think we need to rush a fix
into Git v2.48. The behaviour is preexisting, it's unlikely, and in the
error case we don't misbehave.

Patrick


diff --git a/builtin/gc.c b/builtin/gc.c
index a9b1c36de27..3e754f25bba 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -1909,7 +1909,7 @@ static int get_random_minute(void)
 	if (getenv("GIT_TEST_MAINT_SCHEDULER"))
 		return 13;
 
-	return git_rand() % 60;
+	return git_rand(0) % 60;
 }
 
 static int is_launchctl_available(void)
diff --git a/reftable/stack.c b/reftable/stack.c
index 531660a49f0..8427c49026c 100644
--- a/reftable/stack.c
+++ b/reftable/stack.c
@@ -659,7 +659,7 @@ int reftable_stack_add(struct reftable_stack *st,
 static int format_name(struct reftable_buf *dest, uint64_t min, uint64_t max)
 {
 	char buf[100];
-	uint32_t rnd = (uint32_t)git_rand();
+	uint32_t rnd = (uint32_t)git_rand(CSPRNG_BYTES_INSECURE);
 	snprintf(buf, sizeof(buf), "0x%012" PRIx64 "-0x%012" PRIx64 "-%08x",
 		 min, max, rnd);
 	reftable_buf_reset(dest);
diff --git a/t/helper/test-csprng.c b/t/helper/test-csprng.c
index a4a0aca6177..c86dcc4870f 100644
--- a/t/helper/test-csprng.c
+++ b/t/helper/test-csprng.c
@@ -15,7 +15,7 @@ int cmd__csprng(int argc, const char **argv)
 
 	while (count) {
 		unsigned long chunk = count < sizeof(buf) ? count : sizeof(buf);
-		if (csprng_bytes(buf, chunk) < 0) {
+		if (csprng_bytes(buf, chunk, 0) < 0) {
 			perror("failed to read");
 			return 5;
 		}
diff --git a/t/unit-tests/t-reftable-readwrite.c b/t/unit-tests/t-reftable-readwrite.c
index 6b75a419b9d..f22b9775639 100644
--- a/t/unit-tests/t-reftable-readwrite.c
+++ b/t/unit-tests/t-reftable-readwrite.c
@@ -108,8 +108,8 @@ static void t_log_buffer_size(void)
 	   hash, to ensure that the compressed part is larger than the original.
 	*/
 	for (i = 0; i < REFTABLE_HASH_SIZE_SHA1; i++) {
-		log.value.update.old_hash[i] = (uint8_t)(git_rand() % 256);
-		log.value.update.new_hash[i] = (uint8_t)(git_rand() % 256);
+		log.value.update.old_hash[i] = (uint8_t)(git_rand(0) % 256);
+		log.value.update.new_hash[i] = (uint8_t)(git_rand(0) % 256);
 	}
 	reftable_writer_set_limits(w, update_index, update_index);
 	err = reftable_writer_add_log(w, &log);
@@ -325,7 +325,7 @@ static void t_log_zlib_corruption(void)
 	};
 
 	for (i = 0; i < sizeof(message) - 1; i++)
-		message[i] = (uint8_t)(git_rand() % 64 + ' ');
+		message[i] = (uint8_t)(git_rand(0) % 64 + ' ');
 
 	reftable_writer_set_limits(w, 1, 1);
 
diff --git a/wrapper.c b/wrapper.c
index fa79fd6ec9e..8b985931490 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -479,7 +479,7 @@ int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
 	for (count = 0; count < TMP_MAX; ++count) {
 		int i;
 		uint64_t v;
-		if (csprng_bytes(&v, sizeof(v)) < 0)
+		if (csprng_bytes(&v, sizeof(v), 0) < 0)
 			return error_errno("unable to get random bytes for temporary file");
 
 		/* Fill in the random bits. */
@@ -750,7 +750,7 @@ int open_nofollow(const char *path, int flags)
 #endif
 }
 
-int csprng_bytes(void *buf, size_t len)
+int csprng_bytes(void *buf, size_t len, MAYBE_UNUSED unsigned flags)
 {
 #if defined(HAVE_ARC4RANDOM) || defined(HAVE_ARC4RANDOM_LIBBSD)
 	/* This function never returns an error. */
@@ -785,14 +785,18 @@ int csprng_bytes(void *buf, size_t len)
 		return -1;
 	return 0;
 #elif defined(HAVE_OPENSSL_CSPRNG)
-	int res = RAND_bytes(buf, len);
-	if (res == 1)
+	switch (RAND_pseudo_bytes(buf, len)) {
+	case 1:
 		return 0;
-	if (res == -1)
-		errno = ENOTSUP;
-	else
+	case 0:
+		if (flags & CSPRNG_BYTES_INSECURE)
+			return 0;
 		errno = EIO;
-	return -1;
+		return -1;
+	default:
+		errno = ENOTSUP;
+		return -1;
+	}
 #else
 	ssize_t res;
 	char *p = buf;
@@ -816,11 +820,11 @@ int csprng_bytes(void *buf, size_t len)
 #endif
 }
 
-uint32_t git_rand(void)
+uint32_t git_rand(unsigned flags)
 {
 	uint32_t result;
 
-	if (csprng_bytes(&result, sizeof(result)) < 0)
+	if (csprng_bytes(&result, sizeof(result), flags) < 0)
 		die(_("unable to get random bytes"));
 
 	return result;
diff --git a/wrapper.h b/wrapper.h
index a6b3e1f09ec..7df824e34a9 100644
--- a/wrapper.h
+++ b/wrapper.h
@@ -127,18 +127,26 @@ int open_nofollow(const char *path, int flags);
 
 void sleep_millisec(int millisec);
 
+enum {
+	/*
+	 * Accept insecure bytes, which some CSPRNG implementations may return
+	 * in case the entropy pool has been exhausted.
+	 */
+	CSPRNG_BYTES_INSECURE = (1 << 0),
+};
+
 /*
  * Generate len bytes from the system cryptographically secure PRNG.
  * Returns 0 on success and -1 on error, setting errno.  The inability to
- * satisfy the full request is an error.
+ * satisfy the full request is an error. Accepts CSPRNG flags.
  */
-int csprng_bytes(void *buf, size_t len);
+int csprng_bytes(void *buf, size_t len, unsigned flags);
 
 /*
  * Returns a random uint32_t, uniformly distributed across all possible
- * values.
+ * values. Accepts CSPRNG flags.
  */
-uint32_t git_rand(void);
+uint32_t git_rand(unsigned flags);
 
 /* Provide log2 of the given `size_t`. */
 static inline unsigned log2u(uintmax_t sz)
diff mbox series

Patch

--- expect      2025-01-07 01:39:05 +0000
+++ actual      2025-01-07 01:40:41 +0000
@@ -37,14 +37,12 @@ 
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-37
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-38
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-39
-68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-40
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-41
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-42
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-43
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-44
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-45
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-46
-68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-47
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-48
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-49
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-50
@@ -59,20 +57,16 @@ 
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-59
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-60
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-61
-68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-62
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-63
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-64
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-65
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-66
-68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-67
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-68
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-69
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-70
-68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-71
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-72
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-73
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-74
-68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-75
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-76
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-77
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-78
@@ -80,21 +74,16 @@ 
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-80
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-81
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-82
-68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-83
-68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-84
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-85
-68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-86
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-87
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-88
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-89
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-90
-68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-91
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-92
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-93
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-94
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-95
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-96
-68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-97
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-98
 68d032e9edd3481ac96382786ececc37ec28709e commit        refs/heads/branch-99
 68d032e9edd3481ac96382786ececc37ec28709e commit