fstyp: Fix some memory safety bugs

In the hammer2 label reader, make sure to check for a NULL return from
read_buf().

In the NTFS label reader,
- Avoid an infinite loop if a record length is 0.
- Avoid walking past the end of the buffer.
- When a label is found, avoid reading past the end of the buffer.

PR:		278281
Reviewed by:	emaste
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D47292
This commit is contained in:
Mark Johnston 2024-10-28 13:51:58 +00:00
parent 2ac644317e
commit 878ede1a0d
2 changed files with 26 additions and 12 deletions

View File

@ -220,6 +220,8 @@ read_label(FILE *fp, char *label, size_t size)
broot.data_off = (i * HAMMER2_ZONE_BYTES64) | HAMMER2_PBUFRADIX;
vols[i] = read_buf(fp, broot.data_off & ~HAMMER2_OFF_MASK_RADIX,
sizeof(*vols[i]));
if (vols[i] == NULL)
errx(1, "failed to read volume header");
broot.mirror_tid = vols[i]->voldata.mirror_tid;
if (best_i < 0 || best.mirror_tid < broot.mirror_tid) {
best_i = i;

View File

@ -137,9 +137,8 @@ fstyp_ntfs(FILE *fp, char *label, size_t size)
struct ntfs_filerec *fr;
struct ntfs_attr *atr;
off_t voloff;
char *ap;
int8_t mftrecsz;
int recsize;
size_t recsize;
#endif /* WITH_ICONV */
filerecp = NULL;
@ -152,7 +151,8 @@ fstyp_ntfs(FILE *fp, char *label, size_t size)
goto ok;
mftrecsz = bf->bf_mftrecsz;
recsize = (mftrecsz > 0) ? (mftrecsz * bf->bf_bps * bf->bf_spc) : (1 << -mftrecsz);
recsize = (mftrecsz > 0) ?
(mftrecsz * bf->bf_bps * bf->bf_spc) : (1 << -mftrecsz);
voloff = bf->bf_mftcn * bf->bf_spc * bf->bf_bps +
recsize * NTFS_VOLUMEINO;
@ -165,16 +165,28 @@ fstyp_ntfs(FILE *fp, char *label, size_t size)
if (fr->fr_hdrmagic != NTFS_FILEMAGIC)
goto fail;
for (ap = filerecp + fr->fr_attroff;
atr = (struct ntfs_attr *)ap, (int)atr->a_type != -1;
ap += atr->reclen) {
if (atr->a_type != NTFS_A_VOLUMENAME)
continue;
convert_label(ap + atr->a_dataoff,
atr->a_datalen, label, size);
break;
for (size_t ioff = fr->fr_attroff;
ioff + sizeof(struct ntfs_attr) < recsize;
ioff += atr->reclen) {
atr = (struct ntfs_attr *)(filerecp + ioff);
if ((int)atr->a_type == -1)
goto ok;
if (atr->a_type == NTFS_A_VOLUMENAME) {
if ((size_t)atr->a_dataoff + atr->a_datalen > recsize) {
warnx("ntfs: Volume name attribute overflow");
goto fail;
}
convert_label(filerecp + ioff + atr->a_dataoff,
atr->a_datalen, label, size);
goto ok;
}
if (atr->reclen == 0) {
warnx("ntfs: Invalid attribute record length");
goto fail;
}
}
warnx("ntfs: Volume name not found");
goto fail;
ok:
#else