]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/fileio: simplify calculation of buffer size in read_full_virtual_file()
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 25 Mar 2021 10:58:35 +0000 (11:58 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 26 Mar 2021 14:46:44 +0000 (15:46 +0100)
We'd first assign a value up to SSIZE_MAX, and then immediately check if we
have a value bigger than READ_FULL_BYTES_MAX. This wasn't exactly wrong, but a
bit roundabout. Let's immediately assign the value from the appropriate range
or error out.

Coverity CID#1450973.

src/basic/fileio.c

index 6e42b60c3fe7568d95b0034f993700efc17a6b06..46ab5db79f852c6660bbdfa462096d44a88953b2 100644 (file)
@@ -403,18 +403,22 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re
                         return -EBADF;
 
                 /* Be prepared for files from /proc which generally report a file size of 0. */
+                assert_cc(READ_FULL_BYTES_MAX < SSIZE_MAX);
                 if (st.st_size > 0) {
-                        if (st.st_size > SSIZE_MAX) /* safety check in case off_t is 64bit and size_t 32bit */
+                        if (st.st_size > READ_FULL_BYTES_MAX)
                                 return -E2BIG;
 
                         size = st.st_size;
                         n_retries--;
-                } else
-                        /* Double the buffer size (saturate in case of overflow) */
-                        size = size > SSIZE_MAX / 2 ? SSIZE_MAX : size * 2;
-
-                if (size > READ_FULL_BYTES_MAX)
-                        return -E2BIG;
+                } else {
+                        /* Double the buffer size */
+                        if (size >= READ_FULL_BYTES_MAX)
+                                return -E2BIG;
+                        if (size > READ_FULL_BYTES_MAX / 2)
+                                size = READ_FULL_BYTES_MAX; /* clamp to max */
+                        else
+                                size *= 2;
+                }
 
                 buf = malloc(size + 1);
                 if (!buf)