Patchwork genext2fs: patch for fixing inode based symlink string length limit

login
register
mail settings
Submitter Alexander Stohr
Date July 20, 2011, 1:26 p.m.
Message ID <20110720132636.276450@gmx.net>
Download mbox | patch
Permalink /patch/8055/
State New, archived
Headers show

Comments

Alexander Stohr - July 20, 2011, 1:26 p.m.
below patch fixes a problem with symlinks where the target string had exactly 59 chars and the needed terminating null character.

(where the problem hits: when a fs with such entries gets checked by e2fsck
then those tool detects it as a problem and offers to delete that symlink.
if running an automated fixing cycle it would kill me all those symlinks.)

regards, Alex.

PS: in a test bed with a generated image file i am further seeing a note from e2fsck about a fs with revision zero but feature flags are set.
thats reported as a fs problem and a fix is suggested by a y/n query.

Patch

diff -Nru genext2fs-1.4.1.orig/genext2fs.c genext2fs-1.4.1/genext2fs.c
--- genext2fs-1.4.1.orig/genext2fs.c	2011-07-20 10:57:24.000000000 +0200
+++ genext2fs-1.4.1/genext2fs.c	2011-07-20 14:34:11.000000000 +0200
@@ -1415,9 +1415,10 @@ 
 	uint32 nod = mknod_fs(fs, parent_nod, name, FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO, uid, gid, 0, 0, ctime, mtime);
 	extend_blk(fs, nod, 0, - (int)get_nod(fs, nod)->i_blocks / INOBLK);
 	get_nod(fs, nod)->i_size = size;
-	if(size <= 4 * (EXT2_TIND_BLOCK+1))
+	if(size < 4 * (EXT2_TIND_BLOCK+1))
 	{
 		strncpy((char*)get_nod(fs, nod)->i_block, (char*)b, size);
+		((char*)get_nod(fs, nod)->i_block)[size+1] = '\0';
 		return nod;
 	}
 	extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE);
@@ -1643,6 +1644,10 @@ 
 			switch(st.st_mode & S_IFMT)
 			{
 				case S_IFLNK:
+					if((st.st_mode & S_IFMT) == S_IFREG || st.st_size >= 4 * (EXT2_TIND_BLOCK+1))
+						stats->nblocks += (st.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
+					stats->ninodes++;
+					break;
 				case S_IFREG:
 					if((st.st_mode & S_IFMT) == S_IFREG || st.st_size > 4 * (EXT2_TIND_BLOCK+1))
 						stats->nblocks += (st.st_size + BLOCKSIZE - 1) / BLOCKSIZE;