]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Handle edge case in fr_rand_init() and, we suspect, oveflow (CID #1604611) (#5434)
authorJames Jones <jejones3141@gmail.com>
Sun, 12 Jan 2025 20:51:22 +0000 (14:51 -0600)
committerGitHub <noreply@github.com>
Sun, 12 Jan 2025 20:51:22 +0000 (14:51 -0600)
To handle the rare case of not filling fr_rand_pool.randrsl in a single read,
adjust the location passed to read() to skip what was read in a previous
interation. This is done in a way consistent with the handling of this case
in 3.x, which should also deal with the overflow_sink complaint from Coverity.

src/lib/util/rand.c

index fbe9ecca743fb8743a772541678e2a2ac395522a..53d17290f509aa100f98509181d11143fd590fab 100644 (file)
@@ -34,6 +34,8 @@ static _Thread_local bool fr_rand_initialized = false;
 void fr_rand_init(void)
 {
        int fd;
+       uint8_t *p = (uint8_t *) &fr_rand_pool.randrsl[0];
+       uint8_t *end = p + sizeof(fr_rand_pool.randrsl);
 
        if (fr_rand_initialized) return;
 
@@ -42,15 +44,12 @@ void fr_rand_init(void)
 
        fd = open("/dev/urandom", O_RDONLY);
        if (fd >= 0) {
-               size_t total;
-               ssize_t this;
-
-               total = 0;
-               while (total < sizeof(fr_rand_pool.randrsl)) {
-                       this = read(fd, fr_rand_pool.randrsl,
-                                   sizeof(fr_rand_pool.randrsl) - total);
-                       if ((this < 0) && (errno != EINTR)) break;
-                       if (this > 0) total += this;
+               ssize_t rcode;
+
+               while (p < end) {
+                       rcode = read(fd, p, (size_t) (end - p));
+                       if ((rcode < 0) && (errno != EINTR)) break;
+                       if (rcode > 0) p += rcode;
                }
                close(fd);
        } else {