[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: