[RFC PATCH mtd-utils 009/110] mkfs.ubifs: Fix incorrect dir size calculation in encryption scenario

Zhihao Cheng chengzhihao1 at huawei.com
Thu Jun 6 21:24:34 PDT 2024


The size of directory should be the total length of encrypted entry name,
otherwise it could trigger errors while checking filesystem:
 dbg_check_filesystem [ubifs]: directory inode 89 size is 352, but
 calculated size is 400

Fixes: 4c55918dd747d ("Implement filename encryption")
Signed-off-by: Zhihao Cheng <chengzhihao1 at huawei.com>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 8bf073ce..25c49967 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1723,15 +1723,17 @@ static void set_dent_cookie(struct ubifs_dent_node *dent)
  * @name: directory entry name
  * @inum: target inode number of the directory entry
  * @type: type of the target inode
+ * @kname_len: the length of name stored in the directory entry node is
+ *	       returned here
  */
 static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum,
-			 unsigned char type, struct fscrypt_context *fctx)
+			 unsigned char type, struct fscrypt_context *fctx,
+			 int *kname_len)
 {
 	struct ubifs_dent_node *dent = node_buf;
 	union ubifs_key key;
 	struct qstr dname;
 	char *kname;
-	int kname_len;
 	int len;
 
 	dbg_msg(3, "%s ino %lu type %u dir ino %lu", name, (unsigned long)inum,
@@ -1749,7 +1751,7 @@ static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum,
 	set_dent_cookie(dent);
 
 	if (!fctx) {
-		kname_len = dname.len;
+		*kname_len = dname.len;
 		kname = strdup(name);
 		if (!kname)
 			return errmsg("cannot allocate memory");
@@ -1765,18 +1767,18 @@ static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum,
 		if (ret < 0)
 			return ret;
 
-		kname_len = ret;
+		*kname_len = ret;
 	}
 
-	dent_key_init(c, &key, dir_inum, kname, kname_len);
-	dent->nlen = cpu_to_le16(kname_len);
-	memcpy(dent->name, kname, kname_len);
-	dent->name[kname_len] = '\0';
-	len = UBIFS_DENT_NODE_SZ + kname_len + 1;
+	dent_key_init(c, &key, dir_inum, kname, *kname_len);
+	dent->nlen = cpu_to_le16(*kname_len);
+	memcpy(dent->name, kname, *kname_len);
+	dent->name[*kname_len] = '\0';
+	len = UBIFS_DENT_NODE_SZ + *kname_len + 1;
 
 	key_write(&key, dent->key);
 
-	return add_node(&key, kname, kname_len, dent, len);
+	return add_node(&key, kname, *kname_len, dent, len);
 }
 
 /**
@@ -2026,7 +2028,7 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 {
 	struct dirent *entry;
 	DIR *dir = NULL;
-	int err = 0;
+	int kname_len, err = 0;
 	loff_t size = UBIFS_INO_NODE_SZ;
 	char *name = NULL;
 	unsigned int nlink = 2;
@@ -2139,13 +2141,13 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 			goto out_free;
 		}
 
-		err = add_dent_node(dir_inum, entry->d_name, inum, type, fctx);
+		err = add_dent_node(dir_inum, entry->d_name, inum, type, fctx,
+				    &kname_len);
 		if (err) {
 			free_fscrypt_context(new_fctx);
 			goto out_free;
 		}
-		size += ALIGN(UBIFS_DENT_NODE_SZ + strlen(entry->d_name) + 1,
-			      8);
+		size += ALIGN(UBIFS_DENT_NODE_SZ + kname_len + 1, 8);
 
 		if (new_fctx)
 			free_fscrypt_context(new_fctx);
@@ -2210,13 +2212,14 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 			goto out_free;
 		}
 
-		err = add_dent_node(dir_inum, nh_elt->name, inum, type, fctx);
+		err = add_dent_node(dir_inum, nh_elt->name, inum, type, fctx,
+				    &kname_len);
 		if (err) {
 			free_fscrypt_context(new_fctx);
 			goto out_free;
 		}
 
-		size += ALIGN(UBIFS_DENT_NODE_SZ + strlen(nh_elt->name) + 1, 8);
+		size += ALIGN(UBIFS_DENT_NODE_SZ + kname_len + 1, 8);
 
 		nh_elt = next_name_htbl_element(ph_elt, &itr);
 		if (new_fctx)
-- 
2.13.6




More information about the linux-mtd mailing list