The dumpcg() function in dumpfs(8) uses fs_contigsumsize and
cg_clustersumoff from the filesystem image without validation.

At line 390-396:

  if (afs.fs_contigsumsize > 0) {
      for (i = 1; i < afs.fs_contigsumsize; i++) {
          printf("\t%d", cg_clustersum(&acg)[i]);

cg_clustersum() returns a pointer into the cylinder group buffer
at the offset specified by cg_clustersumoff.  With a corrupted
image, either the offset or the size can be large enough to read
past the buffer (which is fs_bsize bytes), causing a SIGSEGV.

Confirmed on OpenBSD 7.8/arm64 with a mutated FFS image.

Fix: validate that cg_clustersumoff is within the buffer and
that fs_contigsumsize entries fit within the remaining space.

Found by AFL++ fuzzing.

Index: sbin/dumpfs/dumpfs.c
===================================================================
RCS file: /cvs/src/sbin/dumpfs/dumpfs.c,v
retrieving revision 1.39
diff -u -p -r1.39 dumpfs.c
--- sbin/dumpfs/dumpfs.c        9 May 2024 08:35:40 -0000       1.39
+++ sbin/dumpfs/dumpfs.c
@@ -387,7 +387,10 @@ dumpcg(const char *name, int fd, u_int c
                j += i * acg.cg_frsum[i];
        }
        printf("\nsum of frsum: %d", j);
-       if (afs.fs_contigsumsize > 0) {
+       if (afs.fs_contigsumsize > 0 &&
+           acg.cg_clustersumoff < afs.fs_bsize &&
+           afs.fs_contigsumsize <= (afs.fs_bsize -
+           acg.cg_clustersumoff) / (int)sizeof(int32_t)) {
                for (i = 1; i < afs.fs_contigsumsize; i++) {
                        if ((i - 1) % 8 == 0)
                                printf("\nclusters %d-%d:", i,

Reply via email to