Browse Source

romfs: check the dirent before use it

System will crash when the romfs is erased. Add checks before using them
to avoid it.
Grissiom 10 years ago
parent
commit
e882597f9c
1 changed files with 28 additions and 4 deletions
  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,