summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrissiom <[email protected]>2014-11-03 12:10:25 +0800
committerGrissiom <[email protected]>2014-11-03 12:10:25 +0800
commite882597f9c167cac2a79bdbe1a257987dfc83c01 (patch)
tree352e5adc2cd51a66ef54e99c201e45103f50e6db
parent3531fa71aaab7110da240e25b02967f714e44232 (diff)
romfs: check the dirent before use it
System will crash when the romfs is erased. Add checks before using them to avoid it.
-rw-r--r--components/dfs/filesystems/romfs/dfs_romfs.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/components/dfs/filesystems/romfs/dfs_romfs.c b/components/dfs/filesystems/romfs/dfs_romfs.c
index 03df8a88c5..86e7ac88a0 100644
--- a/components/dfs/filesystems/romfs/dfs_romfs.c
+++ b/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,