diff options
author | Stefan Fritsch <sf@cvs.openbsd.org> | 2023-04-30 17:16:37 +0000 |
---|---|---|
committer | Stefan Fritsch <sf@cvs.openbsd.org> | 2023-04-30 17:16:37 +0000 |
commit | e31dbdb65fdfea19f60eb826a4214b2361558e74 (patch) | |
tree | 98b86434524756c2750c1f20c5630b4fed531d68 | |
parent | bdebf4c645a309c488f5cbfdd909f76c44d7117f (diff) |
msdosfs: Never allocate clusters outside the volume
- Assert that usemap_alloc() and usemap_free() cluster number argument
is valid.
- In chainlength(), return 0 if cluster start is after the max cluster.
- In chainlength(), cut the calculated cluster chain length at the max
cluster.
Adapted from FreeBSD commit 097a1d5fbb7990980f8f806c6878537c964adf32
ok miod@
-rw-r--r-- | sys/msdosfs/msdosfs_fat.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/sys/msdosfs/msdosfs_fat.c b/sys/msdosfs/msdosfs_fat.c index c15b6257d43..d31abf7d11d 100644 --- a/sys/msdosfs/msdosfs_fat.c +++ b/sys/msdosfs/msdosfs_fat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: msdosfs_fat.c,v 1.34 2021/03/11 13:31:35 jsg Exp $ */ +/* $OpenBSD: msdosfs_fat.c,v 1.35 2023/04/30 17:16:36 sf Exp $ */ /* $NetBSD: msdosfs_fat.c,v 1.26 1997/10/17 11:24:02 ws Exp $ */ /*- @@ -409,6 +409,7 @@ updatefats(struct msdosfsmount *pmp, struct buf *bp, uint32_t fatbn) static __inline void usemap_alloc(struct msdosfsmount *pmp, uint32_t cn) { + KASSERT(cn <= pmp->pm_maxcluster); pmp->pm_inusemap[cn / N_INUSEBITS] |= 1 << (cn % N_INUSEBITS); pmp->pm_freeclustercount--; @@ -417,6 +418,7 @@ usemap_alloc(struct msdosfsmount *pmp, uint32_t cn) static __inline void usemap_free(struct msdosfsmount *pmp, uint32_t cn) { + KASSERT(cn <= pmp->pm_maxcluster); pmp->pm_freeclustercount++; pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1 << (cn % N_INUSEBITS)); @@ -644,6 +646,8 @@ chainlength(struct msdosfsmount *pmp, uint32_t start, uint32_t count) u_int map; uint32_t len; + if (start > pmp->pm_maxcluster) + return (0); max_idx = pmp->pm_maxcluster / N_INUSEBITS; idx = start / N_INUSEBITS; start %= N_INUSEBITS; @@ -651,11 +655,15 @@ chainlength(struct msdosfsmount *pmp, uint32_t start, uint32_t count) map &= ~((1 << start) - 1); if (map) { len = ffs(map) - 1 - start; - return (len > count ? count : len); + len = MIN(len, count); + len = MIN(len, pmp->pm_maxcluster - start + 1); + return (len); } len = N_INUSEBITS - start; - if (len >= count) - return (count); + if (len >= count) { + len = MIN(count, pmp->pm_maxcluster - start + 1); + return (len); + } while (++idx <= max_idx) { if (len >= count) break; @@ -665,7 +673,9 @@ chainlength(struct msdosfsmount *pmp, uint32_t start, uint32_t count) } len += N_INUSEBITS; } - return (len > count ? count : len); + len = MIN(len, count); + len = MIN(len, pmp->pm_maxcluster - start + 1); + return (len); } /* |