geom_label: Add more validation for NTFS volume tasting
- Ensure that the computed MFT record size isn't negative or larger than maxphys before trying to read $Volume. - Guard against truncated records in volume metadata. - Ensure that the record length is large enough to contain the volume name. - Verify that the (UTF-16-encoded) volume name's length is a multiple of two. PR: 258833, 258914 MFC after: 2 weeks Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
d43fa8ef53
commit
f0a08fa9f5
@ -99,7 +99,8 @@ g_label_ntfs_taste(struct g_consumer *cp, char *label, size_t size)
|
||||
struct ntfs_filerec *fr;
|
||||
struct ntfs_attr *atr;
|
||||
off_t voloff;
|
||||
char *filerecp, *ap;
|
||||
size_t recoff;
|
||||
char *filerecp;
|
||||
int8_t mftrecsz;
|
||||
char vnchar;
|
||||
int recsize, j;
|
||||
@ -119,8 +120,9 @@ g_label_ntfs_taste(struct g_consumer *cp, char *label, size_t size)
|
||||
goto done;
|
||||
|
||||
mftrecsz = bf->bf_mftrecsz;
|
||||
recsize = (mftrecsz > 0) ? (mftrecsz * bf->bf_bps * bf->bf_spc) : (1 << -mftrecsz);
|
||||
if (recsize == 0 || recsize % pp->sectorsize != 0)
|
||||
recsize = (mftrecsz > 0) ? (mftrecsz * bf->bf_bps * bf->bf_spc) :
|
||||
(1 << -mftrecsz);
|
||||
if (recsize <= 0 || recsize > maxphys || recsize % pp->sectorsize != 0)
|
||||
goto done;
|
||||
|
||||
voloff = bf->bf_mftcn * bf->bf_spc * bf->bf_bps +
|
||||
@ -132,24 +134,33 @@ g_label_ntfs_taste(struct g_consumer *cp, char *label, size_t size)
|
||||
if (filerecp == NULL)
|
||||
goto done;
|
||||
fr = (struct ntfs_filerec *)filerecp;
|
||||
|
||||
if (fr->fr_hdrmagic != NTFS_FILEMAGIC)
|
||||
goto done;
|
||||
|
||||
for (ap = filerecp + fr->fr_attroff;
|
||||
atr = (struct ntfs_attr *)ap, atr->a_type != -1;
|
||||
ap += atr->reclen) {
|
||||
for (recoff = fr->fr_attroff;
|
||||
recoff <= recsize - 2 * sizeof(uint32_t);
|
||||
recoff += atr->reclen) {
|
||||
atr = (struct ntfs_attr *)(filerecp + recoff);
|
||||
if (atr->a_type == -1)
|
||||
break;
|
||||
if (atr->reclen < sizeof(*atr))
|
||||
break;
|
||||
if (recsize - recoff < atr->reclen)
|
||||
break;
|
||||
if (atr->a_type == NTFS_A_VOLUMENAME) {
|
||||
if(atr->a_datalen >= size *2){
|
||||
label[0] = 0;
|
||||
goto done;
|
||||
}
|
||||
if (atr->a_dataoff > atr->reclen ||
|
||||
atr->a_datalen > atr->reclen - atr->a_dataoff)
|
||||
break;
|
||||
|
||||
/*
|
||||
*UNICODE to ASCII.
|
||||
* UNICODE to ASCII.
|
||||
* Should we need to use iconv(9)?
|
||||
*/
|
||||
if (atr->a_datalen >= size * 2 ||
|
||||
atr->a_datalen % 2 != 0)
|
||||
break;
|
||||
for (j = 0; j < atr->a_datalen; j++) {
|
||||
vnchar = *(ap + atr->a_dataoff + j);
|
||||
vnchar = ((char *)atr)[atr->a_dataoff + j];
|
||||
if (j & 1) {
|
||||
if (vnchar) {
|
||||
label[0] = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user