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
This commit is contained in:
Mark Johnston 2021-07-13 17:45:57 -04:00
parent b9ca419a21
commit 7f053a44ae
2 changed files with 2 additions and 9 deletions

View File

@ -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,

View File

@ -747,7 +747,7 @@ g_mirror_ctl_insert(struct gctl_req *req, struct g_class *mp)
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);