[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