Skip to content

Commit

Permalink
fsck_msdosfs: truncate directory entry when the head pointer is invalid.
Browse files Browse the repository at this point in the history
As far as we know, there is no FAT implementation that supported hard
links, and our msdosfs driver assumed one cluster chain is only
referenced by one directory entry and clears it out when the file is
deleted.  On the other hand, the current code would proceed with
checkchain() when the directory entry's head cluster is a valid numbered
cluster without checking if it was a valid head node of a cluster chain.

So if the cluster do not being a chain (e.g. CLUST_FREE, CLUST_BAD),
or was already referenced by another directory entry, this would
trigger an assertion in check_chain() at a later time.

Fix this by giving the user an option to truncate the directory entry
when the head cluster is an invalid cluster, an visited head node,
or not a head node.

Reported by:	NetApp (kevans@)
Reviewed by:	kevans, emaste (no objection)
MFC after:	2 weeks
Differential Revision: https://reviews.freebsd.org/D32699
  • Loading branch information
delphij committed Nov 4, 2021
1 parent 15bd9fa commit 890cae1
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions sbin/fsck_msdosfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,21 @@ checksize(struct fat_descriptor *fat, u_char *p, struct dosDirEntry *dir)
if (dir->head == CLUST_FREE) {
physicalSize = 0;
} else {
if (!fat_is_valid_cl(fat, dir->head))
return FSERROR;
if (!fat_is_valid_cl(fat, dir->head) || !fat_is_cl_head(fat, dir->head)) {
pwarn("Directory entry %s of size %u referencing invalid cluster %u\n",
fullpath(dir), dir->size, dir->head);
if (ask(1, "Truncate")) {
p[28] = p[29] = p[30] = p[31] = 0;
p[26] = p[27] = 0;
if (boot->ClustMask == CLUST32_MASK)
p[20] = p[21] = 0;
dir->size = 0;
dir->head = CLUST_FREE;
return FSDIRMOD;
} else {
return FSERROR;
}
}
ret = checkchain(fat, dir->head, &chainsize);
/*
* Upon return, chainsize would hold the chain length
Expand Down

0 comments on commit 890cae1

Please sign in to comment.