[PATCH] erofs-utils: lib: consolidate erofs_rebuild_get_dentry()
Gao Xiang
hsiangkao at linux.alibaba.com
Fri Jun 20 13:26:16 AEST 2025
- Avoid `memcmps`, which could cause potential out-of-range read risks;
- Replace `strlen()` and `memchr()` with `strchr()`.
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
lib/rebuild.c | 71 +++++++++++++++++++++++++++------------------------
1 file changed, 37 insertions(+), 34 deletions(-)
diff --git a/lib/rebuild.c b/lib/rebuild.c
index d428573..6ae5ddf 100644
--- a/lib/rebuild.c
+++ b/lib/rebuild.c
@@ -71,18 +71,27 @@ static struct erofs_dentry *erofs_rebuild_mkdir(struct erofs_inode *dir,
return d;
}
+struct erofs_dentry *erofs_d_lookup(struct erofs_inode *dir, const char *name)
+{
+ struct erofs_dentry *d;
+
+ list_for_each_entry(d, &dir->i_subdirs, d_child)
+ if (!strcmp(d->name, name))
+ return d;
+ return NULL;
+}
+
struct erofs_dentry *erofs_rebuild_get_dentry(struct erofs_inode *pwd,
char *path, bool aufs, bool *whout, bool *opq, bool to_head)
{
struct erofs_dentry *d = NULL;
- unsigned int len = strlen(path);
char *s = path;
*whout = false;
*opq = false;
- while (s < path + len) {
- char *slash = memchr(s, '/', path + len - s);
+ while (1) {
+ char *slash = strchr(s, '/');
if (slash) {
if (s == slash) {
@@ -90,60 +99,54 @@ struct erofs_dentry *erofs_rebuild_get_dentry(struct erofs_inode *pwd,
continue;
}
*slash = '\0';
+ } else if (*s == '\0') {
+ break;
}
- if (!memcmp(s, ".", 2)) {
- /* null */
- } else if (!memcmp(s, "..", 3)) {
- pwd = pwd->i_parent;
+ if (__erofs_unlikely(is_dot_dotdot(s))) {
+ if (s[1] == '.') {
+ pwd = pwd->i_parent;
+ }
} else {
- struct erofs_inode *inode = NULL;
-
if (aufs && !slash) {
- if (!memcmp(s, AUFS_WH_DIROPQ, sizeof(AUFS_WH_DIROPQ))) {
+ if (!strcmp(s, AUFS_WH_DIROPQ)) {
*opq = true;
break;
}
- if (!memcmp(s, AUFS_WH_PFX, sizeof(AUFS_WH_PFX) - 1)) {
+ if (!strcmp(s, AUFS_WH_PFX)) {
s += sizeof(AUFS_WH_PFX) - 1;
*whout = true;
}
}
- list_for_each_entry(d, &pwd->i_subdirs, d_child) {
- if (!strcmp(d->name, s)) {
- if (d->type != EROFS_FT_DIR && slash)
- return ERR_PTR(-EIO);
- inode = d->inode;
- break;
- }
- }
-
- if (inode) {
- if (to_head) {
+ d = erofs_d_lookup(pwd, s);
+ if (d) {
+ if (d->type != EROFS_FT_DIR) {
+ if (slash)
+ return ERR_PTR(-ENOTDIR);
+ } else if (to_head) {
list_del(&d->d_child);
list_add(&d->d_child, &pwd->i_subdirs);
}
- pwd = inode;
- } else if (!slash) {
- d = erofs_d_alloc(pwd, s);
+ pwd = d->inode;
+ } else if (slash) {
+ d = erofs_rebuild_mkdir(pwd, s);
if (IS_ERR(d))
return d;
- d->type = EROFS_FT_UNKNOWN;
- d->inode = pwd;
} else {
- d = erofs_rebuild_mkdir(pwd, s);
+ d = erofs_d_alloc(pwd, s);
if (IS_ERR(d))
return d;
- pwd = d->inode;
+ d->type = EROFS_FT_UNKNOWN;
+ d->inode = pwd;
}
+ pwd = d->inode;
}
- if (slash) {
- *slash = '/';
- s = slash + 1;
- } else {
+
+ if (!slash)
break;
- }
+ *slash = '/';
+ s = slash + 1;
}
return d;
}
--
2.43.5
More information about the Linux-erofs
mailing list