]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
cephfs-journal-tool: fix segfault during 'journal import' from invalid dump file
authorJos Collin <jcollin@redhat.com>
Wed, 13 Nov 2024 09:55:20 +0000 (15:25 +0530)
committerJos Collin <jcollin@redhat.com>
Tue, 24 Jun 2025 05:13:12 +0000 (10:43 +0530)
Fixes: https://tracker.ceph.com/issues/68928
Signed-off-by: Jos Collin <jcollin@redhat.com>
(cherry picked from commit 01db5d107c6408d5f8e492daec0eb501628cd50f)

src/tools/cephfs/Dumper.cc

index 68a190182dd03cc11892e0640117f4cb24a8fd60..dfda045d6a9c312ef65979698e945c64b14ac0cb 100644 (file)
@@ -229,23 +229,54 @@ int Dumper::undump(const char *dump_file, bool force)
   char buf[HEADER_LEN];
   r = safe_read(fd, buf, sizeof(buf));
   if (r < 0) {
+    derr << "Error reading " << dump_file << dendl;
+    VOID_TEMP_FAILURE_RETRY(::close(fd));
+    return r;
+  } else if (r == 0) {
+    //Empty file read
+    derr << "No-op since empty journal dump file: " << dump_file << dendl;
     VOID_TEMP_FAILURE_RETRY(::close(fd));
     return r;
   }
 
   long long unsigned start, len, write_pos, format, trimmed_pos;
   long unsigned stripe_unit, stripe_count, object_size;
-  sscanf(strstr(buf, "start offset"), "start offset %llu", &start);
-  sscanf(strstr(buf, "length"), "length %llu", &len);
-  sscanf(strstr(buf, "write_pos"), "write_pos %llu", &write_pos);
-  sscanf(strstr(buf, "format"), "format %llu", &format);
+  char *phdr = strstr(buf, "start offset");
+  if (phdr == NULL) {
+      derr  << "Invalid header, no 'start offset' embedded" << dendl;
+      ::close(fd);
+      return -EINVAL;
+  }
+  sscanf(phdr, "start offset %llu", &start);
+  phdr = strstr(buf, "length");
+  if (phdr == NULL) {
+      derr  << "Invalid header, no 'length' embedded" << dendl;
+      ::close(fd);
+      return -EINVAL;
+  }
+  sscanf(phdr, "length %llu", &len);
+  phdr = strstr(buf, "write_pos");
+  if (phdr == NULL) {
+      derr  << "Invalid header, no 'write_pos' embedded" << dendl;
+      ::close(fd);
+      return -EINVAL;
+  }
+  sscanf(phdr, "write_pos %llu", &write_pos);
+  phdr = strstr(buf, "format");
+  if (phdr == NULL) {
+      derr  << "Invalid header, no 'format' embedded" << dendl;
+      ::close(fd);
+      return -EINVAL;
+  }
+  sscanf(phdr, "format %llu", &format);
 
   if (!force) {
     // need to check if fsid match onlien cluster fsid
-    if (strstr(buf, "fsid")) {
+    phdr = strstr(buf, "fsid");
+    if (phdr) {
       uuid_d fsid;
       char fsid_str[40];
-      sscanf(strstr(buf, "fsid"), "fsid %39s", fsid_str);
+      sscanf(phdr, "fsid %39s", fsid_str);
       r = fsid.parse(fsid_str);
       if (!r) {
        derr  << "Invalid fsid" << dendl;