mirror of
				https://github.com/qemu/qemu.git
				synced 2025-10-31 20:44:16 +00:00 
			
		
		
		
	 e28ffe90fd
			
		
	
	
		e28ffe90fd
		
	
	
	
	
		
			
			We know that in the body of this if statement i is less than len, so
we really should be copying len - i bytes not i - len bytes.
Fix this typo.
Fixes: 8d8404f156 ("util: Add qemu_guest_getrandom and associated routines")
Signed-off-by: Mark Nelson <mdnelson8@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20210709120600.11080-1-mdnelson8@gmail.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
		
	
			
		
			
				
	
	
		
			102 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * QEMU guest-visible random functions
 | |
|  *
 | |
|  * Copyright 2019 Linaro, Ltd.
 | |
|  *
 | |
|  * This program is free software; you can redistribute it and/or modify it
 | |
|  * under the terms of the GNU General Public License as published by the Free
 | |
|  * Software Foundation; either version 2 of the License, or (at your option)
 | |
|  * any later version.
 | |
|  */
 | |
| 
 | |
| #include "qemu/osdep.h"
 | |
| #include "qemu/cutils.h"
 | |
| #include "qapi/error.h"
 | |
| #include "qemu/guest-random.h"
 | |
| #include "crypto/random.h"
 | |
| #include "sysemu/replay.h"
 | |
| 
 | |
| 
 | |
| static __thread GRand *thread_rand;
 | |
| static bool deterministic;
 | |
| 
 | |
| 
 | |
| static int glib_random_bytes(void *buf, size_t len)
 | |
| {
 | |
|     GRand *rand = thread_rand;
 | |
|     size_t i;
 | |
|     uint32_t x;
 | |
| 
 | |
|     if (unlikely(rand == NULL)) {
 | |
|         /* Thread not initialized for a cpu, or main w/o -seed.  */
 | |
|         thread_rand = rand = g_rand_new();
 | |
|     }
 | |
| 
 | |
|     for (i = 0; i + 4 <= len; i += 4) {
 | |
|         x = g_rand_int(rand);
 | |
|         __builtin_memcpy(buf + i, &x, 4);
 | |
|     }
 | |
|     if (i < len) {
 | |
|         x = g_rand_int(rand);
 | |
|         __builtin_memcpy(buf + i, &x, len - i);
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| int qemu_guest_getrandom(void *buf, size_t len, Error **errp)
 | |
| {
 | |
|     int ret;
 | |
|     if (replay_mode == REPLAY_MODE_PLAY) {
 | |
|         return replay_read_random(buf, len);
 | |
|     }
 | |
|     if (unlikely(deterministic)) {
 | |
|         /* Deterministic implementation using Glib's Mersenne Twister.  */
 | |
|         ret = glib_random_bytes(buf, len);
 | |
|     } else {
 | |
|         /* Non-deterministic implementation using crypto routines.  */
 | |
|         ret = qcrypto_random_bytes(buf, len, errp);
 | |
|     }
 | |
|     if (replay_mode == REPLAY_MODE_RECORD) {
 | |
|         replay_save_random(ret, buf, len);
 | |
|     }
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| void qemu_guest_getrandom_nofail(void *buf, size_t len)
 | |
| {
 | |
|     (void)qemu_guest_getrandom(buf, len, &error_fatal);
 | |
| }
 | |
| 
 | |
| uint64_t qemu_guest_random_seed_thread_part1(void)
 | |
| {
 | |
|     if (deterministic) {
 | |
|         uint64_t ret;
 | |
|         glib_random_bytes(&ret, sizeof(ret));
 | |
|         return ret;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| void qemu_guest_random_seed_thread_part2(uint64_t seed)
 | |
| {
 | |
|     g_assert(thread_rand == NULL);
 | |
|     if (deterministic) {
 | |
|         thread_rand =
 | |
|             g_rand_new_with_seed_array((const guint32 *)&seed,
 | |
|                                        sizeof(seed) / sizeof(guint32));
 | |
|     }
 | |
| }
 | |
| 
 | |
| int qemu_guest_random_seed_main(const char *optarg, Error **errp)
 | |
| {
 | |
|     unsigned long long seed;
 | |
|     if (parse_uint_full(optarg, &seed, 0)) {
 | |
|         error_setg(errp, "Invalid seed number: %s", optarg);
 | |
|         return -1;
 | |
|     } else {
 | |
|         deterministic = true;
 | |
|         qemu_guest_random_seed_thread_part2(seed);
 | |
|         return 0;
 | |
|     }
 | |
| }
 |