Explorar el Código

romfs: check the dirent before use it

System will crash when the romfs is erased. Add checks before using them
to avoid it.
Grissiom hace 11 años
padre
commit
e882597f9c
Se han modificado 1 ficheros con 28 adiciones y 4 borrados
  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;
 	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)
 struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size)
 {
 {
 	rt_size_t index, found;
 	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;
 	struct romfs_dirent *dirent;
 	rt_size_t dirent_size;
 	rt_size_t dirent_size;
 
 
+    /* Check the root_dirent. */
+    if (check_dirent(root_dirent) != 0)
+        return RT_NULL;
+
 	if (path[0] == '/' && path[1] == '\0')
 	if (path[0] == '/' && path[1] == '\0')
 	{
 	{
 		*size = root_dirent->size;
 		*size = root_dirent->size;
@@ -82,6 +94,8 @@ struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const ch
 		/* search in folder */
 		/* search in folder */
 		for (index = 0; index < dirent_size; index ++)
 		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)
 			if (rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
 			{
 			{
 				dirent_size = dirent[index].size;
 				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;
 	dirent = (struct romfs_dirent *)file->data;
 	RT_ASSERT(dirent != RT_NULL);
 	RT_ASSERT(dirent != RT_NULL);
 
 
+    if (check_dirent(dirent) != 0)
+    {
+        return -DFS_STATUS_EIO;
+    }
+
 	if (count < file->size - file->pos)
 	if (count < file->size - file->pos)
 		length = count;
 		length = count;
 	else
 	else
@@ -172,6 +191,9 @@ int dfs_romfs_open(struct dfs_fd *file)
 
 
 	root_dirent = (struct romfs_dirent *)file->fs->data;
 	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))
 	if (file->flags & (DFS_O_CREAT | DFS_O_WRONLY | DFS_O_APPEND | DFS_O_TRUNC | DFS_O_RDWR))
 		return -DFS_STATUS_EINVAL;
 		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;
 	struct romfs_dirent *dirent, *sub_dirent;
 
 
 	dirent = (struct romfs_dirent *)file->data;
 	dirent = (struct romfs_dirent *)file->data;
+    if (check_dirent(dirent) != 0)
+        return -DFS_STATUS_EIO;
 	RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR);
 	RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR);
 
 
 	/* enter directory */
 	/* enter directory */
 	dirent = (struct romfs_dirent *)dirent->data;
 	dirent = (struct romfs_dirent *)dirent->data;
-	
+
 	/* make integer count */
 	/* make integer count */
 	count = (count / sizeof(struct dirent));
 	count = (count / sizeof(struct dirent));
 	if (count == 0)
 	if (count == 0)
 		return -DFS_STATUS_EINVAL;
 		return -DFS_STATUS_EINVAL;
-	
+
 	index = 0;
 	index = 0;
 	for (index = 0; index < count && file->pos < file->size; index ++)
 	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);
 		rt_strncpy(d->d_name, name, rt_strlen(name) + 1);
 
 
 		/* move to next position */
 		/* move to next position */
-		++ file->pos; 
+		++ file->pos;
 	}
 	}
 
 
 	return index * sizeof(struct dirent);
 	return index * sizeof(struct dirent);
 }
 }
 
 
-static const struct dfs_filesystem_operation _romfs = 
+static const struct dfs_filesystem_operation _romfs =
 {
 {
 	"rom",
 	"rom",
 	DFS_FS_FLAG_DEFAULT,
 	DFS_FS_FLAG_DEFAULT,