فهرست منبع

romfs: check the dirent before use it

System will crash when the romfs is erased. Add checks before using them
to avoid it.
Grissiom 11 سال پیش
والد
کامیت
e882597f9c
1فایلهای تغییر یافته به همراه28 افزوده شده و 4 حذف شده
  1. 28 4
      components/dfs/filesystems/romfs/dfs_romfs.c

+ 28 - 4
components/dfs/filesystems/romfs/dfs_romfs.c

@@ -49,6 +49,14 @@ int dfs_romfs_ioctl(struct dfs_fd *file, int cmd, void *args)
 	return -DFS_STATUS_EIO;
 }
 
+rt_inline int check_dirent(struct romfs_dirent *dirent)
+{
+    if (!(dirent->type == ROMFS_DIRENT_FILE || dirent->type == ROMFS_DIRENT_DIR) ||
+         (dirent->size == 0 || dirent->size == ~0))
+        return -1;
+    return 0;
+}
+
 struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size)
 {
 	rt_size_t index, found;
@@ -56,6 +64,10 @@ struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const ch
 	struct romfs_dirent *dirent;
 	rt_size_t dirent_size;
 
+    /* Check the root_dirent. */
+    if (check_dirent(root_dirent) != 0)
+        return RT_NULL;
+
 	if (path[0] == '/' && path[1] == '\0')
 	{
 		*size = root_dirent->size;
@@ -82,6 +94,8 @@ struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const ch
 		/* search in folder */
 		for (index = 0; index < dirent_size; index ++)
 		{
+            if (check_dirent(&dirent[index]) != 0)
+                return RT_NULL;
 			if (rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
 			{
 				dirent_size = dirent[index].size;
@@ -133,6 +147,11 @@ int dfs_romfs_read(struct dfs_fd *file, void *buf, rt_size_t count)
 	dirent = (struct romfs_dirent *)file->data;
 	RT_ASSERT(dirent != RT_NULL);
 
+    if (check_dirent(dirent) != 0)
+    {
+        return -DFS_STATUS_EIO;
+    }
+
 	if (count < file->size - file->pos)
 		length = count;
 	else
@@ -172,6 +191,9 @@ int dfs_romfs_open(struct dfs_fd *file)
 
 	root_dirent = (struct romfs_dirent *)file->fs->data;
 
+    if (check_dirent(dirent) != 0)
+        return -DFS_STATUS_EIO;
+
 	if (file->flags & (DFS_O_CREAT | DFS_O_WRONLY | DFS_O_APPEND | DFS_O_TRUNC | DFS_O_RDWR))
 		return -DFS_STATUS_EINVAL;
 
@@ -236,16 +258,18 @@ int dfs_romfs_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t cou
 	struct romfs_dirent *dirent, *sub_dirent;
 
 	dirent = (struct romfs_dirent *)file->data;
+    if (check_dirent(dirent) != 0)
+        return -DFS_STATUS_EIO;
 	RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR);
 
 	/* enter directory */
 	dirent = (struct romfs_dirent *)dirent->data;
-	
+
 	/* make integer count */
 	count = (count / sizeof(struct dirent));
 	if (count == 0)
 		return -DFS_STATUS_EINVAL;
-	
+
 	index = 0;
 	for (index = 0; index < count && file->pos < file->size; index ++)
 	{
@@ -265,13 +289,13 @@ int dfs_romfs_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t cou
 		rt_strncpy(d->d_name, name, rt_strlen(name) + 1);
 
 		/* move to next position */
-		++ file->pos; 
+		++ file->pos;
 	}
 
 	return index * sizeof(struct dirent);
 }
 
-static const struct dfs_filesystem_operation _romfs = 
+static const struct dfs_filesystem_operation _romfs =
 {
 	"rom",
 	DFS_FS_FLAG_DEFAULT,