summaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/aws-c-common/source/posix/device_random.c
diff options
context:
space:
mode:
authorshadchin <[email protected]>2024-12-03 17:05:42 +0300
committershadchin <[email protected]>2024-12-03 18:21:15 +0300
commit6388569551ef4720bdcd3f07af43fedbecabc847 (patch)
tree279445f9bbee9b4f7b518fde918e49b4c00566c0 /contrib/restricted/aws/aws-c-common/source/posix/device_random.c
parent528eb8de83d25bf28f3d4a1202155523477ad4ac (diff)
Update contrib/restricted/aws/aws-c-common to 0.8.23
commit_hash:ee9e58d849fe0a4add15cf37c9a8899e88291b18
Diffstat (limited to 'contrib/restricted/aws/aws-c-common/source/posix/device_random.c')
-rw-r--r--contrib/restricted/aws/aws-c-common/source/posix/device_random.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/contrib/restricted/aws/aws-c-common/source/posix/device_random.c b/contrib/restricted/aws/aws-c-common/source/posix/device_random.c
index f446002231b..23ab1cd7b44 100644
--- a/contrib/restricted/aws/aws-c-common/source/posix/device_random.c
+++ b/contrib/restricted/aws/aws-c-common/source/posix/device_random.c
@@ -35,23 +35,40 @@ static void s_init_rand(void *user_data) {
}
}
-static int s_fallback_device_random_buffer(struct aws_byte_buf *output) {
+int aws_device_random_buffer_append(struct aws_byte_buf *output, size_t n) {
+ AWS_PRECONDITION(aws_byte_buf_is_valid(output));
aws_thread_call_once(&s_rand_init, s_init_rand, NULL);
- size_t diff = output->capacity - output->len;
+ size_t space_available = output->capacity - output->len;
+ if (space_available < n) {
+ AWS_POSTCONDITION(aws_byte_buf_is_valid(output));
+ return aws_raise_error(AWS_ERROR_SHORT_BUFFER);
+ }
- ssize_t amount_read = read(s_rand_fd, output->buffer + output->len, diff);
+ size_t original_len = output->len;
- if (amount_read != diff) {
- return aws_raise_error(AWS_ERROR_RANDOM_GEN_FAILED);
- }
+ /* read() can fail if N is too large (e.g. x64 macos fails if N > INT32_MAX),
+ * so work in reasonably sized chunks. */
+ while (n > 0) {
+ size_t capped_n = aws_min_size(n, 1024 * 1024 * 1024 * 1 /* 1GiB */);
+
+ ssize_t amount_read = read(s_rand_fd, output->buffer + output->len, capped_n);
- output->len += diff;
+ if (amount_read <= 0) {
+ output->len = original_len;
+ AWS_POSTCONDITION(aws_byte_buf_is_valid(output));
+ return aws_raise_error(AWS_ERROR_RANDOM_GEN_FAILED);
+ }
+
+ output->len += amount_read;
+ n -= amount_read;
+ }
+ AWS_POSTCONDITION(aws_byte_buf_is_valid(output));
return AWS_OP_SUCCESS;
}
int aws_device_random_buffer(struct aws_byte_buf *output) {
- return s_fallback_device_random_buffer(output);
+ return aws_device_random_buffer_append(output, output->capacity - output->len);
}