linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tao Ma <tm@tao.ma>
To: linux-ext4@vger.kernel.org
Subject: [PATCH V6 09/23] ext4: Refactor __ext4_check_dir_entry to accepts start and size.
Date: Fri, 14 Sep 2012 19:24:57 +0800	[thread overview]
Message-ID: <1347621911-4104-9-git-send-email-tm@tao.ma> (raw)
In-Reply-To: <1347621911-4104-1-git-send-email-tm@tao.ma>

From: Tao Ma <boyu.mt@taobao.com>

__ext4_check_dir_entry is used to check whether the de is over
the block boundary. Now with inline data, it could be within the
block boundary while exceeds the inode size. So check this function
to check the overflow more precisely.

Signed-off-by: Tao Ma <boyu.mt@taobao.com>
---
 fs/ext4/dir.c   |   16 ++++++++--------
 fs/ext4/ext4.h  |    7 ++++---
 fs/ext4/namei.c |   13 +++++++++----
 3 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 8e07d2a..7c9d08b 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -72,7 +72,7 @@ static int is_dx_dir(struct inode *inode)
 int __ext4_check_dir_entry(const char *function, unsigned int line,
 			   struct inode *dir, struct file *filp,
 			   struct ext4_dir_entry_2 *de,
-			   struct buffer_head *bh,
+			   struct buffer_head *bh, char *buf, int size,
 			   unsigned int offset)
 {
 	const char *error_msg = NULL;
@@ -85,9 +85,8 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
 		error_msg = "rec_len % 4 != 0";
 	else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len)))
 		error_msg = "rec_len is too small for name_len";
-	else if (unlikely(((char *) de - bh->b_data) + rlen >
-			  dir->i_sb->s_blocksize))
-		error_msg = "directory entry across blocks";
+	else if (unlikely(((char *) de - buf) + rlen > size))
+		error_msg = "directory entry across range";
 	else if (unlikely(le32_to_cpu(de->inode) >
 			le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count)))
 		error_msg = "inode out of bounds";
@@ -98,14 +97,14 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
 		ext4_error_file(filp, function, line, bh->b_blocknr,
 				"bad entry in directory: %s - offset=%u(%u), "
 				"inode=%u, rec_len=%d, name_len=%d",
-				error_msg, (unsigned) (offset % bh->b_size),
+				error_msg, (unsigned) (offset % size),
 				offset, le32_to_cpu(de->inode),
 				rlen, de->name_len);
 	else
 		ext4_error_inode(dir, function, line, bh->b_blocknr,
 				"bad entry in directory: %s - offset=%u(%u), "
 				"inode=%u, rec_len=%d, name_len=%d",
-				error_msg, (unsigned) (offset % bh->b_size),
+				error_msg, (unsigned) (offset % size),
 				offset, le32_to_cpu(de->inode),
 				rlen, de->name_len);
 
@@ -221,8 +220,9 @@ revalidate:
 		while (!error && filp->f_pos < inode->i_size
 		       && offset < sb->s_blocksize) {
 			de = (struct ext4_dir_entry_2 *) (bh->b_data + offset);
-			if (ext4_check_dir_entry(inode, filp, de,
-						 bh, offset)) {
+			if (ext4_check_dir_entry(inode, filp, de, bh,
+						 bh->b_data, bh->b_size,
+						 offset)) {
 				/*
 				 * On error, skip the f_pos to the next block
 				 */
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 1b93b1c..69c2c96 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1928,10 +1928,11 @@ ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);
 extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *,
 				  struct file *,
 				  struct ext4_dir_entry_2 *,
-				  struct buffer_head *, unsigned int);
-#define ext4_check_dir_entry(dir, filp, de, bh, offset)			\
+				  struct buffer_head *, char *, int,
+				  unsigned int);
+#define ext4_check_dir_entry(dir, filp, de, bh, buf, size, offset)	\
 	unlikely(__ext4_check_dir_entry(__func__, __LINE__, (dir), (filp), \
-					(de), (bh), (offset)))
+					(de), (bh), (buf), (size), (offset)))
 extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
 				    __u32 minor_hash,
 				    struct ext4_dir_entry_2 *dirent);
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 8f4ef4b..cb9b2b8 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -857,6 +857,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
 					   EXT4_DIR_REC_LEN(0));
 	for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) {
 		if (ext4_check_dir_entry(dir, NULL, de, bh,
+				bh->b_data, bh->b_size,
 				(block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb))
 					 + ((char *)de - bh->b_data))) {
 			/* On error, skip the f_pos to the next block. */
@@ -1095,7 +1096,8 @@ static inline int search_dirblock(struct buffer_head *bh,
 		if ((char *) de + namelen <= dlimit &&
 		    ext4_match (namelen, name, de)) {
 			/* found a match - just to be sure, do a full check */
-			if (ext4_check_dir_entry(dir, NULL, de, bh, offset))
+			if (ext4_check_dir_entry(dir, NULL, de, bh, bh->b_data,
+						 bh->b_size, offset))
 				return -1;
 			*res_dir = de;
 			return 1;
@@ -1584,7 +1586,8 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
 		de = (struct ext4_dir_entry_2 *)bh->b_data;
 		top = bh->b_data + (blocksize - csum_size) - reclen;
 		while ((char *) de <= top) {
-			if (ext4_check_dir_entry(dir, NULL, de, bh, offset))
+			if (ext4_check_dir_entry(dir, NULL, de, bh, bh->b_data,
+						 bh->b_size, offset))
 				return -EIO;
 			if (ext4_match(namelen, name, de))
 				return -EEXIST;
@@ -2004,7 +2007,8 @@ static int ext4_delete_entry(handle_t *handle,
 	pde = NULL;
 	de = (struct ext4_dir_entry_2 *) bh->b_data;
 	while (i < bh->b_size - csum_size) {
-		if (ext4_check_dir_entry(dir, NULL, de, bh, i))
+		if (ext4_check_dir_entry(dir, NULL, de, bh,
+					 bh->b_data, bh->b_size, i))
 			return -EIO;
 		if (de == de_del)  {
 			BUFFER_TRACE(bh, "get_write_access");
@@ -2357,7 +2361,8 @@ static int empty_dir(struct inode *inode)
 			set_buffer_verified(bh);
 			de = (struct ext4_dir_entry_2 *) bh->b_data;
 		}
-		if (ext4_check_dir_entry(inode, NULL, de, bh, offset)) {
+		if (ext4_check_dir_entry(inode, NULL, de, bh,
+					 bh->b_data, bh->b_size, offset)) {
 			de = (struct ext4_dir_entry_2 *)(bh->b_data +
 							 sb->s_blocksize);
 			offset = (offset | (sb->s_blocksize - 1)) + 1;
-- 
1.7.1


  parent reply	other threads:[~2012-09-14 11:25 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-14 11:18 [PATCH V6 00/23] ext4: Add inline data support Tao Ma
2012-09-14 11:24 ` [PATCH V6 01/23] ext4: Move extra inode read to a new function Tao Ma
2012-09-14 11:24   ` [PATCH V6 02/23] ext4: export inline xattr functions Tao Ma
2012-09-14 11:24   ` [PATCH V6 03/23] ext4: Add the basic function for inline data support Tao Ma
2012-09-14 11:24   ` [PATCH V6 04/23] ext4: Add read support for inline data Tao Ma
2012-09-14 11:24   ` [PATCH V6 05/23] ext4: Add normal write " Tao Ma
2012-09-14 11:24   ` [PATCH V6 06/23] ext4: Add journalled " Tao Ma
2012-09-14 11:24   ` [PATCH V6 07/23] ext4: Add delalloc " Tao Ma
2012-09-14 11:24   ` [PATCH V6 08/23] ext4: Make ext4_init_dot_dotdot for inline dir usage Tao Ma
2012-09-14 11:24   ` Tao Ma [this message]
2012-09-14 11:24   ` [PATCH V6 10/23] ext4: Create __ext4_insert_dentry for dir entry insertion Tao Ma
2012-09-14 11:24   ` [PATCH V6 11/23] ext4: let add_dir_entry handle inline data properly Tao Ma
2012-09-14 11:25   ` [PATCH V6 12/23] ext4: Let ext4_readdir handle inline data Tao Ma
2012-09-14 11:25   ` [PATCH V6 13/23] ext4: Create a new function search_dir Tao Ma
2012-09-14 11:25   ` [PATCH V6 14/23] ext4: let ext4_find_entry handle inline data Tao Ma
2012-09-14 11:25   ` [PATCH V6 15/23] ext4: make ext4_delete_entry generic Tao Ma
2012-09-14 11:25   ` [PATCH V6 16/23] ext4: let ext4_delete_entry handle inline data Tao Ma
2012-09-14 11:25   ` [PATCH V6 17/23] ext4: let empty_dir handle inline dir Tao Ma
2012-09-14 11:25   ` [PATCH V6 18/23] ext4: let ext4_rename " Tao Ma
2012-09-14 11:25   ` [PATCH V6 19/23] ext4: Let fiemap work with inline data Tao Ma
2012-09-14 11:25   ` [PATCH V6 20/23] ext4: Evict inline data out if we needs to strore xattr in inode Tao Ma
2012-09-14 11:25   ` [PATCH V6 21/23] ext4: let ext4_truncate handle inline data correctly Tao Ma
2012-09-14 11:25   ` [PATCH V6 22/23] ext4: let fallocate " Tao Ma
2012-09-14 11:25   ` [PATCH V6 23/23] ext4: Enable ext4 inline support Tao Ma

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1347621911-4104-9-git-send-email-tm@tao.ma \
    --to=tm@tao.ma \
    --cc=linux-ext4@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).