[PATCH 1/2] erofs-utils: fsck: fix outside destination directory exploit

Guo Xuenan guoxuenan at huawei.com
Wed May 31 17:26:11 AEST 2023


In some crafted erofs image, fsck.erofs may write outside
destination directory, which may be used to do some very
dangerous things.

This commit fix this exploit by checking all directory
entry names. Squashfs also met same situation [1], and
already fixed it here [2].

[1]: https://github.com/plougher/squashfs-tools/issues/72
[2]: https://github.com/plougher/squashfs-tools/commit/79b5a555058eef4e1e7ff220c344d39f8cd09646
Signed-off-by: Guo Xuenan <guoxuenan at huawei.com>
---
 lib/dir.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/lib/dir.c b/lib/dir.c
index cb8c188..074e7c3 100644
--- a/lib/dir.c
+++ b/lib/dir.c
@@ -4,6 +4,24 @@
 #include "erofs/print.h"
 #include "erofs/dir.h"
 
+/*
+ * Check name for validity, name should not
+ *  - have a "/" anywhere in the name, or
+ *  - be shorter than the expected size
+ */
+static int erofs_check_name(const char *dname, int size)
+{
+	char *name = (char *)dname;
+
+	while (*name != '/' && *name != '\0' && (name - dname < size))
+		name++;
+	if (*name == '/')
+		return false;
+	if ((name - dname) != size)
+		return false;
+	return true;
+}
+
 static int traverse_dirents(struct erofs_dir_context *ctx,
 			    void *dentry_blk, unsigned int lblk,
 			    unsigned int next_nameoff, unsigned int maxsize,
@@ -101,6 +119,9 @@ static int traverse_dirents(struct erofs_dir_context *ctx,
 				}
 				break;
 			}
+		} else if (!erofs_check_name(de_name, de_namelen)) {
+			errmsg = "corrupted dirent with illegal characters";
+			goto out;
 		}
 		ret = ctx->cb(ctx);
 		if (ret) {
-- 
2.31.1



More information about the Linux-erofs mailing list