From 7f053a44aef75eab395ce15a1c8a1399a2f89cad Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 13 Jul 2021 17:45:57 -0400 Subject: [PATCH] gmirror: Zero the metadata block before writing The mirror metadata fields contain string buffers and pad bytes, neither were being zeroed before metadata was written to disk. Also, the metadata structure is smaller than the sector size, and in one case gmirror was failing to zero-fill the full buffer before writing. Fix these problems by pre-zeroing the metadata structure and the sector buffer. Reported by: KMSAN MFC after: 2 weeks Sponsored by: The FreeBSD Foundation --- sys/geom/mirror/g_mirror.c | 9 +-------- sys/geom/mirror/g_mirror_ctl.c | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index 51836b7eabb..c0641d15673 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -749,6 +749,7 @@ g_mirror_fill_metadata(struct g_mirror_softc *sc, struct g_mirror_disk *disk, struct g_mirror_metadata *md) { + bzero(md, sizeof(*md)); strlcpy(md->md_magic, G_MIRROR_MAGIC, sizeof(md->md_magic)); md->md_version = G_MIRROR_VERSION; strlcpy(md->md_name, sc->sc_name, sizeof(md->md_name)); @@ -760,14 +761,8 @@ g_mirror_fill_metadata(struct g_mirror_softc *sc, struct g_mirror_disk *disk, md->md_mediasize = sc->sc_mediasize; md->md_sectorsize = sc->sc_sectorsize; md->md_mflags = (sc->sc_flags & G_MIRROR_DEVICE_FLAG_MASK); - bzero(md->md_provider, sizeof(md->md_provider)); if (disk == NULL) { md->md_did = arc4random(); - md->md_priority = 0; - md->md_syncid = 0; - md->md_dflags = 0; - md->md_sync_offset = 0; - md->md_provsize = 0; } else { md->md_did = disk->d_id; md->md_priority = disk->d_priority; @@ -775,8 +770,6 @@ g_mirror_fill_metadata(struct g_mirror_softc *sc, struct g_mirror_disk *disk, md->md_dflags = (disk->d_flags & G_MIRROR_DISK_FLAG_MASK); if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) md->md_sync_offset = disk->d_sync.ds_offset_done; - else - md->md_sync_offset = 0; if ((disk->d_flags & G_MIRROR_DISK_FLAG_HARDCODED) != 0) { strlcpy(md->md_provider, disk->d_consumer->provider->name, diff --git a/sys/geom/mirror/g_mirror_ctl.c b/sys/geom/mirror/g_mirror_ctl.c index 254841b6c04..355504a6f90 100644 --- a/sys/geom/mirror/g_mirror_ctl.c +++ b/sys/geom/mirror/g_mirror_ctl.c @@ -747,7 +747,7 @@ again: bzero(md.md_provider, sizeof(md.md_provider)); } md.md_provsize = pp->mediasize; - sector = g_malloc(pp->sectorsize, M_WAITOK); + sector = g_malloc(pp->sectorsize, M_WAITOK | M_ZERO); mirror_metadata_encode(&md, sector); error = g_write_data(disks[i].consumer, pp->mediasize - pp->sectorsize, sector, pp->sectorsize);