git: 4c89c0127dca - main - g_raid concat: Fail requests to read beyond the end of the volume
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 04 Aug 2023 23:43:07 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=4c89c0127dcadaa0d337c23d028f3fea5e76317a
commit 4c89c0127dcadaa0d337c23d028f3fea5e76317a
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2023-08-04 23:41:05 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2023-08-04 23:41:05 +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
---
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 eac62b3171d2..632501f323cd 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, void *virtual,
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, void *virtual,
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);
}
}