kern/77234: corrupted data is read from UDF filesystem if read
starts at non-aligned offset
Andriy Gapon
avg at icyb.net.ua
Mon Feb 7 13:40:23 PST 2005
The following reply was made to PR kern/77234; it has been noted by GNATS.
From: Andriy Gapon <avg at icyb.net.ua>
To: FreeBSD-gnats-submit at FreeBSD.org, freebsd-bugs at FreeBSD.org
Cc:
Subject: Re: kern/77234: corrupted data is read from UDF filesystem if read
starts at non-aligned offset
Date: Mon, 7 Feb 2005 23:31:30 +0200 (EET)
If meaning of max_size is interpreted as maximum number of contiguous
bytes that can be read starting from a given offset rather than starting
from a beginning of a calculated sector number then a patch could be like
the following. (Please note that currently max_size contains number of
bytes in an extent to which current offset belongs, which is total
nonsense since any code that calls udf_bmap_internal() has no notion of
extents)
--- udf_vnops.c.orig Mon Feb 7 22:59:34 2005
+++ udf_vnops.c Mon Feb 7 23:18:06 2005
@@ -1107,19 +1107,21 @@
*size = max_size;
*size = min(*size, MAXBSIZE);
- if ((error = udf_readlblks(udfmp, sector, *size, bp))) {
+ if ((error = udf_readlblks(udfmp, sector, *size + (offset & udfmp->bmask), bp))) {
printf("warning: udf_readlblks returned error %d\n", error);
return (error);
}
bp1 = *bp;
- *data = (uint8_t *)&bp1->b_data[offset % udfmp->bsize];
+ *data = (uint8_t *)&bp1->b_data[offset & udfmp->bmask];
return (0);
}
/*
* Translate a file offset into a logical block and then into a physical
* block.
+ * max_size - maximum number of bytes that can be read starting from given
+ * offset, not beginning of calculated sector number
*/
static int
udf_bmap_internal(struct udf_node *node, off_t offset, daddr_t *sector, uint32_t *max_size)
@@ -1172,7 +1174,7 @@
lsector = (offset >> udfmp->bshift) +
((struct short_ad *)(icb))->pos;
- *max_size = GETICBLEN(short_ad, icb);
+ *max_size = icblen - offset;
break;
case 1:
@@ -1196,7 +1198,7 @@
lsector = (offset >> udfmp->bshift) +
((struct long_ad *)(icb))->loc.lb_num;
- *max_size = GETICBLEN(long_ad, icb);
+ *max_size = icblen - offset;
break;
case 3:
More information about the freebsd-bugs
mailing list