summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@cvs.openbsd.org>2014-06-18 17:29:08 +0000
committerTobias Stoeckmann <tobias@cvs.openbsd.org>2014-06-18 17:29:08 +0000
commit9802c1340125bbb2877e684e6a88360e099f0b4e (patch)
tree9c5176a90d62ba86f9015b911d4bf62cfbe2323c
parent97d7ed8e5ab617c099737cd491ed46054dd988e6 (diff)
Always keep length of cluster chain up to date, otherwise the drop of
superfluous clusters can lead to out of boundary access. ok krw@
-rw-r--r--sbin/fsck_msdos/dir.c12
-rw-r--r--sbin/fsck_msdos/fat.c11
2 files changed, 18 insertions, 5 deletions
diff --git a/sbin/fsck_msdos/dir.c b/sbin/fsck_msdos/dir.c
index 38baedc8042..0459a7f96d2 100644
--- a/sbin/fsck_msdos/dir.c
+++ b/sbin/fsck_msdos/dir.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dir.c,v 1.22 2014/06/16 18:33:33 tobias Exp $ */
+/* $OpenBSD: dir.c,v 1.23 2014/06/18 17:29:07 tobias Exp $ */
/* $NetBSD: dir.c,v 1.11 1997/10/17 11:19:35 ws Exp $ */
/*
@@ -374,7 +374,7 @@ checksize(struct bootblock *boot, struct fatEntry *fat, u_char *p,
/*
* Check size on ordinary files
*/
- int32_t physicalSize;
+ u_int32_t physicalSize;
if (dir->head == CLUST_FREE)
physicalSize = 0;
@@ -400,12 +400,16 @@ checksize(struct bootblock *boot, struct fatEntry *fat, u_char *p,
fullpath(dir));
if (ask(1, "Drop superfluous clusters")) {
cl_t cl;
- u_int32_t sz = 0;
+ u_int32_t len, sz;
- for (cl = dir->head; (sz += boot->ClusterSize) < dir->size;)
+ len = sz = 0;
+ for (cl = dir->head; (sz += boot->ClusterSize) < dir->size;) {
cl = fat[cl].next;
+ len++;
+ }
clearchain(boot, fat, fat[cl].next);
fat[cl].next = CLUST_EOF;
+ fat[dir->head].length = len;
return (FSFATMOD);
} else
return (FSERROR);
diff --git a/sbin/fsck_msdos/fat.c b/sbin/fsck_msdos/fat.c
index 1eb517bf641..1ab8c7380f2 100644
--- a/sbin/fsck_msdos/fat.c
+++ b/sbin/fsck_msdos/fat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fat.c,v 1.23 2014/06/16 18:33:33 tobias Exp $ */
+/* $OpenBSD: fat.c,v 1.24 2014/06/18 17:29:07 tobias Exp $ */
/* $NetBSD: fat.c,v 1.8 1997/10/17 11:19:53 ws Exp $ */
/*
@@ -302,11 +302,20 @@ clearchain(struct bootblock *boot, struct fatEntry *fat, cl_t head)
int
tryclear(struct bootblock *boot, struct fatEntry *fat, cl_t head, cl_t *trunc)
{
+ u_int len;
+ cl_t p;
+
if (ask(0, "Clear chain starting at %u", head)) {
clearchain(boot, fat, head);
return FSFATMOD;
} else if (ask(0, "Truncate")) {
*trunc = CLUST_EOF;
+ len = 0;
+ for (p = head; p >= CLUST_FIRST && p < boot->NumClusters;
+ p = fat[p].next) {
+ len++;
+ }
+ fat[head].length = len;
return FSFATMOD;
} else
return FSERROR;