git: 0f6ffc7ff301 - stable/12 - g_raid concat: Fail requests to read beyond the end of the volume
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 06 Sep 2023 21:57:02 UTC
The branch stable/12 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=0f6ffc7ff3018d54857c361d251d0c89ab88ec0e commit 0f6ffc7ff3018d54857c361d251d0c89ab88ec0e Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2023-08-04 23:41:05 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2023-09-06 20:02:51 +0000 g_raid concat: Fail requests to read beyond the end of the volume Previously a debug kernel would trigger an assertion failure if an I/O request attempted to read off the end of a concat volume, but a non-debug kernel would use an invalid sub-disk to try to complete the request eventually resulting in some sort of fault in the kernel. Instead, turn the assertions into explicit checks that fail requests beyond the end of the volume with EIO. For requests which run over the end of the volume, return a short request. PR: 257838 Reported by: Robert Morris <rtm@lcs.mit.edu> Reviewed by: emaste MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D41222 (cherry picked from commit 4c89c0127dcadaa0d337c23d028f3fea5e76317a) --- sys/geom/raid/tr_concat.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/sys/geom/raid/tr_concat.c b/sys/geom/raid/tr_concat.c index 97d7111fe801..1e9a803b2054 100644 --- a/sys/geom/raid/tr_concat.c +++ b/sys/geom/raid/tr_concat.c @@ -240,8 +240,10 @@ g_raid_tr_iostart_concat(struct g_raid_tr_object *tr, struct bio *bp) offset -= vol->v_subdisks[no].sd_size; no++; } - KASSERT(no < vol->v_disks_count, - ("Request starts after volume end (%ju)", bp->bio_offset)); + if (no >= vol->v_disks_count) { + g_raid_iodone(bp, EIO); + return; + } bioq_init(&queue); do { sd = &vol->v_subdisks[no]; @@ -267,10 +269,8 @@ g_raid_tr_iostart_concat(struct g_raid_tr_object *tr, struct bio *bp) addr += length; offset = 0; no++; - KASSERT(no < vol->v_disks_count || remain == 0, - ("Request ends after volume end (%ju, %ju)", - bp->bio_offset, bp->bio_length)); - } while (remain > 0); + } while (remain > 0 && no < vol->v_disks_count); + bp->bio_completed = bp->bio_length - remain; while ((cbp = bioq_takefirst(&queue)) != NULL) { sd = cbp->bio_caller1; cbp->bio_caller1 = NULL; @@ -308,8 +308,8 @@ g_raid_tr_kerneldump_concat(struct g_raid_tr_object *tr, offset -= vol->v_subdisks[no].sd_size; no++; } - KASSERT(no < vol->v_disks_count, - ("Request starts after volume end (%ju)", boffset)); + if (no >= vol->v_disks_count) + return (EIO); do { sd = &vol->v_subdisks[no]; length = MIN(sd->sd_size - offset, remain); @@ -321,10 +321,9 @@ g_raid_tr_kerneldump_concat(struct g_raid_tr_object *tr, addr += length; offset = 0; no++; - KASSERT(no < vol->v_disks_count || remain == 0, - ("Request ends after volume end (%ju, %zu)", - boffset, blength)); - } while (remain > 0); + } while (remain > 0 && no < vol->v_disks_count); + if (remain > 0) + return (EIO); return (0); } @@ -340,7 +339,6 @@ g_raid_tr_iodone_concat(struct g_raid_tr_object *tr, g_destroy_bio(bp); pbp->bio_inbed++; if (pbp->bio_children == pbp->bio_inbed) { - pbp->bio_completed = pbp->bio_length; g_raid_iodone(pbp, pbp->bio_error); } }