lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Sat, 10 Mar 2007 12:32:19 +0300
From:	Evgeniy Dushistov <dushistov@...l.ru>
To:	akpm@...ux-foundation.org, linux-kernel@...r.kernel.org
Cc:	linux-fsdevel@...r.kernel.org
Subject: [PATCH 3/4]: ufs: zeroize the rest of block in truncate

This patch fix behaviour in such test scenario:

lseek(fd, BIG_OFFSET)
write(fd, buf, sizeof(buf))
truncate(BIG_OFFSET)
truncate(BIG_OFFSET + sizeof(buf))
read(fd, buf...)

Because of if file big enough(BIG_OFFSET) we start allocate
space by block, ordinary block size > page size,
so we should zeroize the rest of block in truncate(except last framgnet,
about which VFS should care), to not get garbage,
when we extend file.

Also patch corrects conversation
from pointer to block to physical block number,
this helps in case of not common used UFS types.

And add to debug output inode number.

Signed-off-by: Evgeniy Dushistov <dushistov@...l.ru>

---

Index: linux-2.6.21-rc3-git6/fs/ufs/truncate.c
===================================================================
--- linux-2.6.21-rc3-git6.orig/fs/ufs/truncate.c
+++ linux-2.6.21-rc3-git6/fs/ufs/truncate.c
@@ -74,7 +74,7 @@ static int ufs_trunc_direct(struct inode
 	unsigned i, tmp;
 	int retry;
 	
-	UFSD("ENTER\n");
+	UFSD("ENTER: ino %lu\n", inode->i_ino);
 
 	sb = inode->i_sb;
 	uspi = UFS_SB(sb)->s_uspi;
@@ -96,8 +96,8 @@ static int ufs_trunc_direct(struct inode
 		block2 = ufs_fragstoblks (frag3);
 	}
 
-	UFSD("frag1 %llu, frag2 %llu, block1 %llu, block2 %llu, frag3 %llu,"
-	     " frag4 %llu\n",
+	UFSD("ino %lu, frag1 %llu, frag2 %llu, block1 %llu, block2 %llu,"
+	     " frag3 %llu, frag4 %llu\n", inode->i_ino,
 	     (unsigned long long)frag1, (unsigned long long)frag2,
 	     (unsigned long long)block1, (unsigned long long)block2,
 	     (unsigned long long)frag3, (unsigned long long)frag4);
@@ -163,7 +163,7 @@ next1:
 	mark_inode_dirty(inode);
  next3:
 
-	UFSD("EXIT\n");
+	UFSD("EXIT: ino %lu\n", inode->i_ino);
 	return retry;
 }
 
@@ -248,7 +248,7 @@ static int ufs_trunc_indirect(struct ino
 	}
 	ubh_brelse (ind_ubh);
 	
-	UFSD("EXIT\n");
+	UFSD("EXIT: ino %lu\n", inode->i_ino);
 	
 	return retry;
 }
@@ -262,7 +262,7 @@ static int ufs_trunc_dindirect(struct in
 	void *dind;
 	int retry = 0;
 	
-	UFSD("ENTER\n");
+	UFSD("ENTER: ino %lu\n", inode->i_ino);
 	
 	sb = inode->i_sb;
 	uspi = UFS_SB(sb)->s_uspi;
@@ -312,7 +312,7 @@ static int ufs_trunc_dindirect(struct in
 	}
 	ubh_brelse (dind_bh);
 	
-	UFSD("EXIT\n");
+	UFSD("EXIT: ino %lu\n", inode->i_ino);
 	
 	return retry;
 }
@@ -327,7 +327,7 @@ static int ufs_trunc_tindirect(struct in
 	void *tind, *p;
 	int retry;
 	
-	UFSD("ENTER\n");
+	UFSD("ENTER: ino %lu\n", inode->i_ino);
 
 	retry = 0;
 	
@@ -372,19 +372,21 @@ static int ufs_trunc_tindirect(struct in
 	}
 	ubh_brelse (tind_bh);
 	
-	UFSD("EXIT\n");
+	UFSD("EXIT: ino %lu\n", inode->i_ino);
 	return retry;
 }
 
 static int ufs_alloc_lastblock(struct inode *inode)
 {
 	int err = 0;
+	struct super_block *sb = inode->i_sb;
 	struct address_space *mapping = inode->i_mapping;
-	struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi;
+	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
 	unsigned i, end;
 	sector_t lastfrag;
 	struct page *lastpage;
 	struct buffer_head *bh;
+	u64 phys64;
 
 	lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift;
 
@@ -424,6 +426,20 @@ static int ufs_alloc_lastblock(struct in
 	       set_page_dirty(lastpage);
        }
 
+       if (lastfrag >= UFS_IND_FRAGMENT) {
+	       end = uspi->s_fpb - ufs_fragnum(lastfrag) - 1;
+	       phys64 = bh->b_blocknr + 1;
+	       for (i = 0; i < end; ++i) {
+		       bh = sb_getblk(sb, i + phys64);
+		       lock_buffer(bh);
+		       memset(bh->b_data, 0, sb->s_blocksize);
+		       set_buffer_uptodate(bh);
+		       mark_buffer_dirty(bh);
+		       unlock_buffer(bh);
+		       sync_dirty_buffer(bh);
+		       brelse(bh);
+	       }
+       }
 out_unlock:
        ufs_put_locked_page(lastpage);
 out:
Index: linux-2.6.21-rc3-git6/fs/ufs/inode.c
===================================================================
--- linux-2.6.21-rc3-git6.orig/fs/ufs/inode.c
+++ linux-2.6.21-rc3-git6/fs/ufs/inode.c
@@ -212,7 +212,7 @@ repeat:
 			brelse (result);
 			goto repeat;
 		} else {
-			*phys = tmp + blockoff;
+			*phys = uspi->s_sbbase + tmp + blockoff;
 			return NULL;
 		}
 	}
@@ -282,9 +282,9 @@ repeat:
 	}
 
 	if (!phys) {
-		result = sb_getblk(sb, tmp + blockoff);
+		result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff);
 	} else {
-		*phys = tmp + blockoff;
+		*phys = uspi->s_sbbase + tmp + blockoff;
 		result = NULL;
 		*err = 0;
 		*new = 1;
@@ -368,7 +368,7 @@ repeat:
 			brelse (result);
 			goto repeat;
 		} else {
-			*phys = tmp + blockoff;
+			*phys = uspi->s_sbbase + tmp + blockoff;
 			goto out;
 		}
 	}
@@ -389,9 +389,9 @@ repeat:
 
 
 	if (!phys) {
-		result = sb_getblk(sb, tmp + blockoff);
+		result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff);
 	} else {
-		*phys = tmp + blockoff;
+		*phys = uspi->s_sbbase + tmp + blockoff;
 		*new = 1;
 	}
 
Index: linux-2.6.21-rc3-git6/fs/ufs/balloc.c
===================================================================
--- linux-2.6.21-rc3-git6.orig/fs/ufs/balloc.c
+++ linux-2.6.21-rc3-git6/fs/ufs/balloc.c
@@ -482,8 +482,9 @@ u64 ufs_new_fragments(struct inode *inod
 	if (result) {
 		ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
 				locked_page != NULL);
-		ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp,
-				   result, locked_page);
+		ufs_change_blocknr(inode, fragment - oldcount, oldcount,
+				   uspi->s_sbbase + tmp,
+				   uspi->s_sbbase + result, locked_page);
 		ufs_cpu_to_data_ptr(sb, p, result);
 		*err = 0;
 		UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count);
-- 
/Evgeniy

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ