Re: Bug#417673: /sbin/fsck.vfat incorrectly truncates files
tags 417673 + patch
thanks
Hi
The attached patch stolen from http://patches.ubuntu.com/d/dosfstools/dosfstools_2.11-2.1ubuntu3.patch
fixes #417673 for me.
Release team is this too late for etch r0?
Andrew V.
diff -pruN 2.11-2.1/debian/changelog 2.11-2.1ubuntu3/debian/changelog
--- 2.11-2.1/debian/changelog 2006-12-19 05:08:31.000000000 +0000
+++ 2.11-2.1ubuntu3/debian/changelog 2006-12-19 05:08:20.000000000 +0000
@@ -1,3 +1,28 @@
+dosfstools (2.11-2.1ubuntu3) feisty; urgency=low
+
+ * Fix a hang when dosfsck runs out of names for renamed files.
+ - Print an error message instead of doing an infinite loop.
+ - Using the file extension for more available names.
+ Thanks to Onno Benschop for providing the initial fix.
+ Closes: LP#68153.
+
+ -- Stefan Potyra <sistpoty@ubuntu.com> Tue, 19 Dec 2006 03:20:37 +0100
+
+dosfstools (2.11-2.1ubuntu2) feisty; urgency=low
+
+ * Fix some integer overflows in check.c and fat.c which resulted in
+ large files (close to 32-bit limit) being errorenously truncated
+ to 0 bytes. Closes LP#62831.
+
+ -- Stefan Potyra <sistpoty@ubuntu.com> Tue, 19 Dec 2006 02:21:45 +0100
+
+dosfstools (2.11-2.1ubuntu1) dapper; urgency=low
+
+ * Applied patch from Fred (launchpad bug 17960) to correct issue where
+ dosfsck cannot truncate a file if another file shares its clusters.
+
+ -- Daniel Silverstone <daniel.silverstone@ubuntu.com> Mon, 3 Apr 2006 19:05:57 +0100
+
dosfstools (2.11-2.1) unstable; urgency=low
* Non-maintainer upload.
diff -pruN 2.11-2.1/dosfsck/check.c 2.11-2.1ubuntu3/dosfsck/check.c
--- 2.11-2.1/dosfsck/check.c 2005-03-12 15:08:43.000000000 +0000
+++ 2.11-2.1ubuntu3/dosfsck/check.c 2006-12-19 05:08:20.000000000 +0000
@@ -305,14 +305,14 @@ static void truncate_file(DOS_FS *fs,DOS
static void auto_rename(DOS_FILE *file)
{
DOS_FILE *first,*walk;
- int number;
+ unsigned long int number;
if (!file->offset) return; /* cannot rename FAT32 root dir */
first = file->parent ? file->parent->first : root;
number = 0;
while (1) {
- sprintf(file->dir_ent.name,"FSCK%04d",number);
- strncpy(file->dir_ent.ext,"REN",3);
+ sprintf(file->dir_ent.name, "FSCK%04d", number / 1000);
+ sprintf(file->dir_ent.name, "%03d", number % 1000);
for (walk = first; walk; walk = walk->next)
if (walk != file && !strncmp(walk->dir_ent.name,file->dir_ent.
name,MSDOS_NAME)) break;
@@ -321,6 +321,9 @@ static void auto_rename(DOS_FILE *file)
return;
}
number++;
+ if (number > 9999999) {
+ die("Too many files need repair.");
+ }
}
die("Can't generate a unique name.");
}
@@ -450,10 +453,10 @@ static int check_file(DOS_FS *fs,DOS_FIL
break;
}
if (!(file->dir_ent.attr & ATTR_DIR) && CF_LE_L(file->dir_ent.size) <=
- clusters*fs->cluster_size) {
- printf("%s\n File size is %u bytes, cluster chain length is > %lu "
+ (unsigned long long)clusters*fs->cluster_size) {
+ printf("%s\n File size is %u bytes, cluster chain length is > %llu "
"bytes.\n Truncating file to %u bytes.\n",path_name(file),
- CF_LE_L(file->dir_ent.size),clusters*fs->cluster_size,
+ CF_LE_L(file->dir_ent.size),(unsigned long long)clusters*fs->cluster_size,
CF_LE_L(file->dir_ent.size));
truncate_file(fs,file,clusters);
break;
@@ -469,20 +472,20 @@ static int check_file(DOS_FS *fs,DOS_FIL
else clusters2++;
restart = file->dir_ent.attr & ATTR_DIR;
if (!owner->offset) {
- printf( " Truncating second to %lu bytes because first "
- "is FAT32 root dir.\n", clusters2*fs->cluster_size );
+ printf( " Truncating second to %llu bytes because first "
+ "is FAT32 root dir.\n", (unsigned long long)clusters2*fs->cluster_size );
do_trunc = 2;
}
else if (!file->offset) {
- printf( " Truncating first to %lu bytes because second "
- "is FAT32 root dir.\n", clusters*fs->cluster_size );
+ printf( " Truncating first to %llu bytes because second "
+ "is FAT32 root dir.\n", (unsigned long long)clusters*fs->cluster_size );
do_trunc = 1;
}
else if (interactive)
- printf("1) Truncate first to %lu bytes%s\n"
- "2) Truncate second to %lu bytes\n",clusters*fs->cluster_size,
- restart ? " and restart" : "",clusters2*fs->cluster_size);
- else printf(" Truncating second to %lu bytes.\n",clusters2*
+ printf("1) Truncate first to %llu bytes%s\n"
+ "2) Truncate second to %llu bytes\n",(unsigned long long)clusters*fs->cluster_size,
+ restart ? " and restart" : "",(unsigned long long)clusters2*fs->cluster_size);
+ else printf(" Truncating second to %llu bytes.\n",(unsigned long long)clusters2*
fs->cluster_size);
if (do_trunc != 2 &&
(do_trunc == 1 ||
@@ -494,12 +497,13 @@ static int check_file(DOS_FS *fs,DOS_FIL
if (this == curr) {
if (prev) set_fat(fs,prev,-1);
else MODIFY_START(owner,0,fs);
- MODIFY(owner,size,CT_LE_L(clusters*fs->cluster_size));
+ MODIFY(owner,size,CT_LE_L((unsigned long long)clusters*fs->cluster_size));
if (restart) return 1;
while (this > 0 && this != -1) {
set_owner(fs,this,NULL);
this = next_cluster(fs,this);
}
+ this = curr;
break;
}
clusters++;
@@ -520,11 +524,11 @@ static int check_file(DOS_FS *fs,DOS_FIL
prev = curr;
}
if (!(file->dir_ent.attr & ATTR_DIR) && CF_LE_L(file->dir_ent.size) >
- clusters*fs->cluster_size) {
- printf("%s\n File size is %u bytes, cluster chain length is %lu bytes."
+ (unsigned long long)clusters*fs->cluster_size) {
+ printf("%s\n File size is %u bytes, cluster chain length is %llu bytes."
"\n Truncating file to %lu bytes.\n",path_name(file),CF_LE_L(file->
- dir_ent.size),clusters*fs->cluster_size,clusters*fs->cluster_size);
- MODIFY(file,size,CT_LE_L(clusters*fs->cluster_size));
+ dir_ent.size),(unsigned long long)clusters*fs->cluster_size,(unsigned long long)clusters*fs->cluster_size);
+ MODIFY(file,size,CT_LE_L((unsigned long long)clusters*fs->cluster_size));
}
return 0;
}
diff -pruN 2.11-2.1/dosfsck/fat.c 2.11-2.1ubuntu3/dosfsck/fat.c
--- 2.11-2.1/dosfsck/fat.c 2003-06-14 21:03:20.000000000 +0100
+++ 2.11-2.1ubuntu3/dosfsck/fat.c 2006-12-19 05:08:20.000000000 +0000
@@ -54,7 +54,7 @@ void read_fat(DOS_FS *fs)
void *first,*second,*use;
int first_ok,second_ok;
- eff_size = ((fs->clusters+2)*fs->fat_bits+7)/8;
+ eff_size = ((fs->clusters+2ULL)*fs->fat_bits+7)/8ULL;
first = alloc(eff_size);
fs_read(fs->fat_start,eff_size,first);
use = first;
@@ -97,7 +97,7 @@ void read_fat(DOS_FS *fs)
exit(1);
}
}
- fs->fat = qalloc(&mem_queue,sizeof(FAT_ENTRY)*(fs->clusters+2));
+ fs->fat = qalloc(&mem_queue,sizeof(FAT_ENTRY)*(fs->clusters+2ULL));
for (i = 2; i < fs->clusters+2; i++) get_fat(&fs->fat[i],use,i,fs);
for (i = 2; i < fs->clusters+2; i++)
if (fs->fat[i].value >= fs->clusters+2 &&
@@ -177,7 +177,7 @@ unsigned long next_cluster(DOS_FS *fs,un
loff_t cluster_start(DOS_FS *fs,unsigned long cluster)
{
- return fs->data_start+((loff_t)cluster-2)*fs->cluster_size;
+ return fs->data_start+((loff_t)cluster-2)*(unsigned long long)fs->cluster_size;
}
@@ -225,8 +225,8 @@ void reclaim_free(DOS_FS *fs)
reclaimed++;
}
if (reclaimed)
- printf("Reclaimed %d unused cluster%s (%d bytes).\n",reclaimed,
- reclaimed == 1 ? "" : "s",reclaimed*fs->cluster_size);
+ printf("Reclaimed %d unused cluster%s (%llu bytes).\n",reclaimed,
+ reclaimed == 1 ? "" : "s",(unsigned long long)reclaimed*fs->cluster_size);
}
@@ -305,8 +305,8 @@ void reclaim_file(DOS_FS *fs)
fs_write(offset,sizeof(DIR_ENT),&de);
}
if (reclaimed)
- printf("Reclaimed %d unused cluster%s (%d bytes) in %d chain%s.\n",
- reclaimed,reclaimed == 1 ? "" : "s",reclaimed*fs->cluster_size,files,
+ printf("Reclaimed %d unused cluster%s (%llu bytes) in %d chain%s.\n",
+ reclaimed,reclaimed == 1 ? "" : "s",(unsigned long long)reclaimed*fs->cluster_size,files,
files == 1 ? "" : "s");
}
Reply to: