[PATCH 2/5] erofs-utils: fix the wrong name length of tail file in the directory

Huang Jianan jnhuang95 at gmail.com
Fri Oct 16 00:39:56 AEDT 2020


The file name doesn't end with '\0' if it just fill a block, so we shouldn't use strlen to get file name length, fix it.

Signed-off-by: Huang Jianan <huangjianan at oppo.com>
Signed-off-by: Guo Weichao <guoweichao at oppo.com>
---
 fuse/namei.c  | 10 ++++++----
 fuse/readir.c | 14 ++++++++------
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/fuse/namei.c b/fuse/namei.c
index ded9207..21e6ba0 100644
--- a/fuse/namei.c
+++ b/fuse/namei.c
@@ -87,7 +87,8 @@ int erofs_iget_by_nid(erofs_nid_t nid, struct erofs_vnode *vi)
 
 /* dirent + name string */
 struct dcache_entry *list_name(const char *buf, struct dcache_entry *parent,
-				const char *name, unsigned int len)
+				const char *name, unsigned int len,
+				uint32_t dirend)
 {
 	struct dcache_entry *entry = NULL;
 	struct erofs_dirent *ds, *de;
@@ -99,7 +100,8 @@ struct dcache_entry *list_name(const char *buf, struct dcache_entry *parent,
 		erofs_nid_t nid = le64_to_cpu(ds->nid);
 		uint16_t nameoff = le16_to_cpu(ds->nameoff);
 		char *d_name = (char *)(buf + nameoff);
-		uint16_t name_len = (ds + 1 >= de) ? (uint16_t)strlen(d_name) :
+		uint16_t name_len = (ds + 1 >= de) ?
+			(uint16_t)strnlen(d_name, dirend - nameoff) :
 			le16_to_cpu(ds[1].nameoff) - nameoff;
 
 		#if defined(EROFS_DEBUG_ENTRY)
@@ -146,7 +148,7 @@ struct dcache_entry *disk_lookup(struct dcache_entry *parent, const char *name,
 		if (dev_read_blk(buf, blkno + nr_cnt) != EROFS_BLKSIZ)
 			return NULL;
 
-		entry = list_name(buf, parent, name, name_len);
+		entry = list_name(buf, parent, name, name_len, EROFS_BLKSIZ);
 		if (entry)
 			goto next;
 
@@ -163,7 +165,7 @@ struct dcache_entry *disk_lookup(struct dcache_entry *parent, const char *name,
 		if (ret < 0 && (uint32_t)ret != dir_off)
 			return NULL;
 
-		entry = list_name(buf, parent, name, name_len);
+		entry = list_name(buf, parent, name, name_len, dir_off);
 	}
 next:
 	return entry;
diff --git a/fuse/readir.c b/fuse/readir.c
index 367f935..9589685 100644
--- a/fuse/readir.c
+++ b/fuse/readir.c
@@ -17,7 +17,8 @@
 #include "logging.h"
 #include "init.h"
 
-erofs_nid_t split_entry(char *entry, off_t ofs, char *end, char *name)
+erofs_nid_t split_entry(char *entry, off_t ofs, char *end, char *name,
+			uint32_t dirend)
 {
 	struct erofs_dirent *de = (struct erofs_dirent *)(entry + ofs);
 	uint16_t nameoff = le16_to_cpu(de->nameoff);
@@ -25,7 +26,7 @@ erofs_nid_t split_entry(char *entry, off_t ofs, char *end, char *name)
 	uint32_t de_namelen;
 
 	if ((void *)(de + 1) >= (void *)end)
-		de_namelen = strlen(de_name);
+		de_namelen = strnlen(de_name, dirend - nameoff);
 	else
 		de_namelen = le16_to_cpu(de[1].nameoff) - nameoff;
 
@@ -34,7 +35,8 @@ erofs_nid_t split_entry(char *entry, off_t ofs, char *end, char *name)
 	return le64_to_cpu(de->nid);
 }
 
-int fill_dir(char *entrybuf, fuse_fill_dir_t filler, void *buf)
+int fill_dir(char *entrybuf, fuse_fill_dir_t filler, void *buf,
+	     uint32_t dirend)
 {
 	uint32_t ofs;
 	uint16_t nameoff;
@@ -45,7 +47,7 @@ int fill_dir(char *entrybuf, fuse_fill_dir_t filler, void *buf)
 	end = entrybuf + nameoff;
 	ofs = 0;
 	while (ofs < nameoff) {
-		(void)split_entry(entrybuf, ofs, end, name);
+		(void)split_entry(entrybuf, ofs, end, name, dirend);
 		filler(buf, name, NULL, 0);
 		ofs += sizeof(struct erofs_dirent);
 	}
@@ -99,7 +101,7 @@ int erofs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
 		ret = dev_read_blk(dirsbuf, v.raw_blkaddr + nr_cnt);
 		if (ret != EROFS_BLKSIZ)
 			return -EIO;
-		fill_dir(dirsbuf, filler, buf);
+		fill_dir(dirsbuf, filler, buf, EROFS_BLKSIZ);
 		++nr_cnt;
 	}
 
@@ -113,7 +115,7 @@ int erofs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
 		ret = dev_read(dirsbuf, dir_off, addr);
 		if (ret < 0 || (uint32_t)ret != dir_off)
 			return -EIO;
-		fill_dir(dirsbuf, filler, buf);
+		fill_dir(dirsbuf, filler, buf, dir_off);
 	}
 
 	return 0;
-- 
2.25.1



More information about the Linux-erofs mailing list