From c7f3baedf33683b15d8f96497a88532cf64d1d85 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Tue, 29 Apr 2003 19:46:42 +0000 Subject: [PATCH] Fix an obscure fencepost error in GBDE's sector mapping code: For certain combinations of sectorsize, mediasize and random numbers (used to define the mapping), a multisector read or write would ignore some subset of the sectors past the first sector in the request because those sectors would be mapped past the end of the parent device, and normal "end of media" truncation would zap that part of the request. Rev 1.19+1.20 of g_bde_work.c added the check which should have alerted me to this happening. This commit maps the request correctly and adds KASSERTS to make sure things stay inside the parent device. This does not change the on-disk layout of GBDE, there is no need to backup/restore. --- sys/geom/bde/g_bde_crypt.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/sys/geom/bde/g_bde_crypt.c b/sys/geom/bde/g_bde_crypt.c index 93715e80638..f4162c1d97a 100644 --- a/sys/geom/bde/g_bde_crypt.c +++ b/sys/geom/bde/g_bde_crypt.c @@ -331,6 +331,8 @@ g_bde_map_sector(struct g_bde_work *wp) wp->so = zone * kp->zone_width + zoff; wp->so += kp->keyoffset; wp->so %= kp->media_width; + if (wp->so + wp->length > kp->media_width) + wp->length = kp->media_width - wp->so; wp->so += kp->sector0; /* The key sector is the last in this zone. */ @@ -364,4 +366,28 @@ g_bde_map_sector(struct g_bde_work *wp) (intmax_t)wp->kso, wp->ko); #endif + KASSERT(wp->so + wp->length <= kp->sectorN, + ("wp->so (%qd) + wp->length (%qd) > EOM (%qd), offset = %qd", + (intmax_t)wp->so, + (intmax_t)wp->length, + (intmax_t)kp->sectorN, + (intmax_t)wp->offset)); + + KASSERT(wp->kso + kp->sectorsize <= kp->sectorN, + ("wp->kso (%qd) + kp->sectorsize > EOM (%qd), offset = %qd", + (intmax_t)wp->kso, + (intmax_t)kp->sectorN, + (intmax_t)wp->offset)); + + KASSERT(wp->so >= kp->sector0, + ("wp->so (%qd) < BOM (%qd), offset = %qd", + (intmax_t)wp->so, + (intmax_t)kp->sector0, + (intmax_t)wp->offset)); + + KASSERT(wp->kso >= kp->sector0, + ("wp->kso (%qd) kso, + (intmax_t)kp->sector0, + (intmax_t)wp->offset)); }