Merge branch 'ps/reftable-get-random-fix'
The code to compute "unique" name used git_rand() which can fail or get stuck; the callsite does not require cryptographic security. Introduce the "insecure" mode and use it appropriately. * ps/reftable-get-random-fix: reftable/stack: accept insecure random bytes wrapper: allow generating insecure random bytes
This commit is contained in:
@ -1909,7 +1909,7 @@ static int get_random_minute(void)
|
|||||||
if (getenv("GIT_TEST_MAINT_SCHEDULER"))
|
if (getenv("GIT_TEST_MAINT_SCHEDULER"))
|
||||||
return 13;
|
return 13;
|
||||||
|
|
||||||
return git_rand() % 60;
|
return git_rand(0) % 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_launchctl_available(void)
|
static int is_launchctl_available(void)
|
||||||
|
@ -493,7 +493,7 @@ static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st,
|
|||||||
close(fd);
|
close(fd);
|
||||||
fd = -1;
|
fd = -1;
|
||||||
|
|
||||||
delay = delay + (delay * rand()) / RAND_MAX + 1;
|
delay = delay + (delay * git_rand(CSPRNG_BYTES_INSECURE)) / UINT32_MAX + 1;
|
||||||
sleep_millisec(delay);
|
sleep_millisec(delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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)
|
static int format_name(struct reftable_buf *dest, uint64_t min, uint64_t max)
|
||||||
{
|
{
|
||||||
char buf[100];
|
char buf[100];
|
||||||
uint32_t rnd = (uint32_t)git_rand();
|
uint32_t rnd = git_rand(CSPRNG_BYTES_INSECURE);
|
||||||
snprintf(buf, sizeof(buf), "0x%012" PRIx64 "-0x%012" PRIx64 "-%08x",
|
snprintf(buf, sizeof(buf), "0x%012" PRIx64 "-0x%012" PRIx64 "-%08x",
|
||||||
min, max, rnd);
|
min, max, rnd);
|
||||||
reftable_buf_reset(dest);
|
reftable_buf_reset(dest);
|
||||||
|
@ -15,7 +15,7 @@ int cmd__csprng(int argc, const char **argv)
|
|||||||
|
|
||||||
while (count) {
|
while (count) {
|
||||||
unsigned long chunk = count < sizeof(buf) ? count : sizeof(buf);
|
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");
|
perror("failed to read");
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
@ -108,8 +108,8 @@ static void t_log_buffer_size(void)
|
|||||||
hash, to ensure that the compressed part is larger than the original.
|
hash, to ensure that the compressed part is larger than the original.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < REFTABLE_HASH_SIZE_SHA1; i++) {
|
for (i = 0; i < REFTABLE_HASH_SIZE_SHA1; i++) {
|
||||||
log.value.update.old_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() % 256);
|
log.value.update.new_hash[i] = (uint8_t)(git_rand(0) % 256);
|
||||||
}
|
}
|
||||||
reftable_writer_set_limits(w, update_index, update_index);
|
reftable_writer_set_limits(w, update_index, update_index);
|
||||||
err = reftable_writer_add_log(w, &log);
|
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++)
|
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);
|
reftable_writer_set_limits(w, 1, 1);
|
||||||
|
|
||||||
|
24
wrapper.c
24
wrapper.c
@ -479,7 +479,7 @@ int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
|
|||||||
for (count = 0; count < TMP_MAX; ++count) {
|
for (count = 0; count < TMP_MAX; ++count) {
|
||||||
int i;
|
int i;
|
||||||
uint64_t v;
|
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");
|
return error_errno("unable to get random bytes for temporary file");
|
||||||
|
|
||||||
/* Fill in the random bits. */
|
/* Fill in the random bits. */
|
||||||
@ -750,7 +750,7 @@ int open_nofollow(const char *path, int flags)
|
|||||||
#endif
|
#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)
|
#if defined(HAVE_ARC4RANDOM) || defined(HAVE_ARC4RANDOM_LIBBSD)
|
||||||
/* This function never returns an error. */
|
/* This function never returns an error. */
|
||||||
@ -785,14 +785,18 @@ int csprng_bytes(void *buf, size_t len)
|
|||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
#elif defined(HAVE_OPENSSL_CSPRNG)
|
#elif defined(HAVE_OPENSSL_CSPRNG)
|
||||||
int res = RAND_bytes(buf, len);
|
switch (RAND_pseudo_bytes(buf, len)) {
|
||||||
if (res == 1)
|
case 1:
|
||||||
return 0;
|
return 0;
|
||||||
if (res == -1)
|
case 0:
|
||||||
errno = ENOTSUP;
|
if (flags & CSPRNG_BYTES_INSECURE)
|
||||||
else
|
return 0;
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
|
default:
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
ssize_t res;
|
ssize_t res;
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
@ -816,11 +820,11 @@ int csprng_bytes(void *buf, size_t len)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t git_rand(void)
|
uint32_t git_rand(unsigned flags)
|
||||||
{
|
{
|
||||||
uint32_t result;
|
uint32_t result;
|
||||||
|
|
||||||
if (csprng_bytes(&result, sizeof(result)) < 0)
|
if (csprng_bytes(&result, sizeof(result), flags) < 0)
|
||||||
die(_("unable to get random bytes"));
|
die(_("unable to get random bytes"));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
16
wrapper.h
16
wrapper.h
@ -127,18 +127,26 @@ int open_nofollow(const char *path, int flags);
|
|||||||
|
|
||||||
void sleep_millisec(int millisec);
|
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.
|
* Generate len bytes from the system cryptographically secure PRNG.
|
||||||
* Returns 0 on success and -1 on error, setting errno. The inability to
|
* 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
|
* 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`. */
|
/* Provide log2 of the given `size_t`. */
|
||||||
static inline unsigned log2u(uintmax_t sz)
|
static inline unsigned log2u(uintmax_t sz)
|
||||||
|
Reference in New Issue
Block a user