mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-18 14:01:59 +01:00
loader: reading from large dosfs fails
With 8GB disk image and FAT32, our read offset calculation wraps over 32-bit integer and we end up reading garbage. The problem appears when disk image is filled with data and the block to bytes translations do not fit into 32-bit integers. illumos issue: https://www.illumos.org/issues/16666 Sponsored by: MNX Cloud, Inc. MFC after: 1 week
This commit is contained in:
parent
2e9761eb80
commit
fae4b97c1a
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 1998 Robert Nordier
|
||||
* All rights reserved.
|
||||
* Copyright 2024 MNX Cloud, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -139,8 +140,8 @@ static DOS_DE dot[2] = {
|
||||
#define okclus(fs, c) ((c) >= LOCLUS && (c) <= (fs)->xclus)
|
||||
|
||||
/* Get start cluster from directory entry */
|
||||
#define stclus(sz, de) ((sz) != 32 ? cv2((de)->clus) : \
|
||||
((u_int)cv2((de)->dex.h_clus) << 16) | \
|
||||
#define stclus(sz, de) ((sz) != 32 ? (u_int)cv2((de)->clus) : \
|
||||
((u_int)cv2((de)->dex.h_clus) << 16) | \
|
||||
cv2((de)->clus))
|
||||
|
||||
static int parsebs(DOS_FS *, DOS_BS *);
|
||||
@ -152,7 +153,7 @@ static off_t fsize(DOS_FS *, DOS_DE *);
|
||||
static int fatcnt(DOS_FS *, u_int);
|
||||
static int fatget(DOS_FS *, u_int *);
|
||||
static int fatend(u_int, u_int);
|
||||
static int ioread(DOS_FS *, u_int, void *, size_t);
|
||||
static int ioread(DOS_FS *, uint64_t, void *, size_t);
|
||||
static int ioget(struct open_file *, daddr_t, void *, size_t);
|
||||
|
||||
static int
|
||||
@ -364,7 +365,9 @@ static int
|
||||
dos_read(struct open_file *fd, void *buf, size_t nbyte, size_t *resid)
|
||||
{
|
||||
off_t size;
|
||||
u_int nb, off, clus, c, cnt, n;
|
||||
uint64_t off;
|
||||
size_t nb;
|
||||
u_int clus, c, cnt, n;
|
||||
DOS_FILE *f = (DOS_FILE *)fd->f_fsdata;
|
||||
int err = 0;
|
||||
|
||||
@ -375,7 +378,7 @@ dos_read(struct open_file *fd, void *buf, size_t nbyte, size_t *resid)
|
||||
* 4-5 sec.
|
||||
*/
|
||||
twiddle(4);
|
||||
nb = (u_int)nbyte;
|
||||
nb = nbyte;
|
||||
if ((size = fsize(f->fs, &f->de)) == -1)
|
||||
return (EINVAL);
|
||||
if (nb > (n = size - f->offset))
|
||||
@ -402,8 +405,12 @@ dos_read(struct open_file *fd, void *buf, size_t nbyte, size_t *resid)
|
||||
}
|
||||
if (!clus || (n = f->fs->bsize - off) > cnt)
|
||||
n = cnt;
|
||||
if ((err = ioread(f->fs, (c ? blkoff(f->fs, c) :
|
||||
secbyt(f->fs->lsndir)) + off, buf, n)))
|
||||
if (c != 0)
|
||||
off += blkoff(f->fs, (uint64_t)c);
|
||||
else
|
||||
off += secbyt(f->fs->lsndir);
|
||||
err = ioread(f->fs, off, buf, n);
|
||||
if (err != 0)
|
||||
goto out;
|
||||
f->offset += n;
|
||||
f->c = c;
|
||||
@ -908,11 +915,12 @@ fatend(u_int sz, u_int c)
|
||||
* Offset-based I/O primitive
|
||||
*/
|
||||
static int
|
||||
ioread(DOS_FS *fs, u_int offset, void *buf, size_t nbyte)
|
||||
ioread(DOS_FS *fs, uint64_t offset, void *buf, size_t nbyte)
|
||||
{
|
||||
char *s;
|
||||
u_int off, n;
|
||||
size_t n;
|
||||
int err;
|
||||
uint64_t off;
|
||||
u_char local_buf[SECSIZ];
|
||||
|
||||
s = buf;
|
||||
|
Loading…
Reference in New Issue
Block a user