summaryrefslogtreecommitdiffstats
path: root/sys/geom/bde/g_bde_crypt.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-04-29 19:46:42 +0000
committerphk <phk@FreeBSD.org>2003-04-29 19:46:42 +0000
commita43e2a0d8eeff8d49bf239e4b649da2c52cde74a (patch)
tree5bb0d3feb19eb91959e7dbfcc89b85894147c9df /sys/geom/bde/g_bde_crypt.c
parentdf1245285857fc9e563d54987830c04ede93ccce (diff)
downloadFreeBSD-src-a43e2a0d8eeff8d49bf239e4b649da2c52cde74a.zip
FreeBSD-src-a43e2a0d8eeff8d49bf239e4b649da2c52cde74a.tar.gz
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.
Diffstat (limited to 'sys/geom/bde/g_bde_crypt.c')
-rw-r--r--sys/geom/bde/g_bde_crypt.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/geom/bde/g_bde_crypt.c b/sys/geom/bde/g_bde_crypt.c
index 93715e8..f4162c1 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) <BOM (%qd), offset = %qd",
+ (intmax_t)wp->kso,
+ (intmax_t)kp->sector0,
+ (intmax_t)wp->offset));
}
OpenPOWER on IntegriCloud