repo: NUL terminate readlinkat result
authorColin Walters <walters@verbum.org>
Mon, 29 Jul 2024 19:17:10 +0000 (15:17 -0400)
committerColin Walters <walters@verbum.org>
Mon, 29 Jul 2024 21:14:12 +0000 (17:14 -0400)
Coverity was correctly complaining about this.

Signed-off-by: Colin Walters <walters@verbum.org>
src/libostree/ostree-repo-commit.c

index 4d12d5ecb4cde3ba5d068f397a45724a40eea77a..db83ebf240933c9c458b268b0a88542891adc2a8 100644 (file)
@@ -794,7 +794,7 @@ _try_clone_from_payload_link (OstreeRepo *self, OstreeRepo *dest_repo, const cha
       glnx_autofd int fdf = -1;
       char loose_path_buf[_OSTREE_LOOSE_PATH_MAX];
       char loose_path_target_buf[_OSTREE_LOOSE_PATH_MAX];
-      char target_buf[_OSTREE_LOOSE_PATH_MAX + _OSTREE_PAYLOAD_LINK_PREFIX_LEN];
+      char target_buf[_OSTREE_LOOSE_PATH_MAX + _OSTREE_PAYLOAD_LINK_PREFIX_LEN + 1];
       char target_checksum[OSTREE_SHA256_STRING_LEN + 1];
       int dfd = dfd_searches[i];
       ssize_t size;
@@ -804,16 +804,21 @@ _try_clone_from_payload_link (OstreeRepo *self, OstreeRepo *dest_repo, const cha
       _ostree_loose_path (loose_path_buf, payload_checksum, OSTREE_OBJECT_TYPE_PAYLOAD_LINK,
                           self->mode);
 
-      size = TEMP_FAILURE_RETRY (readlinkat (dfd, loose_path_buf, target_buf, sizeof (target_buf)));
+      size = TEMP_FAILURE_RETRY (
+          readlinkat (dfd, loose_path_buf, target_buf, sizeof (target_buf) - 1));
       if (size < 0)
         {
           if (errno == ENOENT)
             continue;
           return glnx_throw_errno_prefix (error, "readlinkat");
         }
+      target_buf[size] = '\0';
 
+      const size_t expected_len = OSTREE_SHA256_STRING_LEN + _OSTREE_PAYLOAD_LINK_PREFIX_LEN;
       if (size < OSTREE_SHA256_STRING_LEN + _OSTREE_PAYLOAD_LINK_PREFIX_LEN)
-        return glnx_throw (error, "invalid data size for %s", loose_path_buf);
+        return glnx_throw (error, "invalid data size for %s; expected=%llu found=%llu",
+                           loose_path_buf, (unsigned long long)expected_len,
+                           (unsigned long long)size);
 
       snprintf (target_checksum, size, "%.2s%.62s", target_buf + _OSTREE_PAYLOAD_LINK_PREFIX_LEN,
                 target_buf + _OSTREE_PAYLOAD_LINK_PREFIX_LEN + 3);