summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgeniusgogo <[email protected]>2023-11-28 17:16:21 +0800
committerGitHub <[email protected]>2023-11-28 17:16:21 +0800
commit74925f43eda4b09bfd26c38beaf366481d784505 (patch)
treeb4fcfa77bca24f1a9adac3906cbbe38ac8e9ab34
parent249871cbbcdc14f1c16a2d502639780ebc6ae078 (diff)
fix dfs path name overflow. (#8305)
-rw-r--r--bsp/simulator/drivers/dfs_win32.c2
-rw-r--r--components/dfs/dfs_v1/filesystems/elmfat/dfs_elm.c2
-rw-r--r--components/dfs/dfs_v1/filesystems/nfs/dfs_nfs.c2
-rw-r--r--components/dfs/dfs_v1/filesystems/romfs/dfs_romfs.c2
-rw-r--r--components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c2
-rw-r--r--components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c28
-rw-r--r--components/dfs/dfs_v2/include/dfs.h6
-rw-r--r--components/dfs/dfs_v2/src/dfs.c11
-rw-r--r--components/dfs/dfs_v2/src/dfs_file.c148
-rw-r--r--components/finsh/msh_file.c10
-rw-r--r--components/lwp/lwp_syscall.c2
11 files changed, 113 insertions, 102 deletions
diff --git a/bsp/simulator/drivers/dfs_win32.c b/bsp/simulator/drivers/dfs_win32.c
index f87b38b38a..1cdc198cc3 100644
--- a/bsp/simulator/drivers/dfs_win32.c
+++ b/bsp/simulator/drivers/dfs_win32.c
@@ -346,7 +346,7 @@ static int dfs_win32_getdents(struct dfs_file *file, struct dirent *dirp, rt_uin
else
d->d_type = DT_REG;
d->d_namlen = (rt_uint8_t)strlen(wdirp->curr);
- strncpy(d->d_name, wdirp->curr, DFS_PATH_MAX);
+ strncpy(d->d_name, wdirp->curr, DIRENT_NAME_MAX);
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
wdirp->curr += (strlen(wdirp->curr) + 1);
file->pos = wdirp->curr - wdirp->start + sizeof(struct dirent);//NOTE!
diff --git a/components/dfs/dfs_v1/filesystems/elmfat/dfs_elm.c b/components/dfs/dfs_v1/filesystems/elmfat/dfs_elm.c
index 5adba36f16..50ec5b6a97 100644
--- a/components/dfs/dfs_v1/filesystems/elmfat/dfs_elm.c
+++ b/components/dfs/dfs_v1/filesystems/elmfat/dfs_elm.c
@@ -674,7 +674,7 @@ int dfs_elm_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
d->d_namlen = (rt_uint8_t)rt_strlen(fn);
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
- rt_strncpy(d->d_name, fn, DFS_PATH_MAX);
+ rt_strncpy(d->d_name, fn, DIRENT_NAME_MAX);
index ++;
if (index * sizeof(struct dirent) >= count)
diff --git a/components/dfs/dfs_v1/filesystems/nfs/dfs_nfs.c b/components/dfs/dfs_v1/filesystems/nfs/dfs_nfs.c
index 9adc5b6c42..b24e636184 100644
--- a/components/dfs/dfs_v1/filesystems/nfs/dfs_nfs.c
+++ b/components/dfs/dfs_v1/filesystems/nfs/dfs_nfs.c
@@ -1144,7 +1144,7 @@ int nfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
d->d_namlen = rt_strlen(name);
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
- rt_strncpy(d->d_name, name, DFS_PATH_MAX);
+ rt_strncpy(d->d_name, name, DIRENT_NAME_MAX);
index ++;
if (index * sizeof(struct dirent) >= count)
diff --git a/components/dfs/dfs_v1/filesystems/romfs/dfs_romfs.c b/components/dfs/dfs_v1/filesystems/romfs/dfs_romfs.c
index 9ecb0819c4..1ae48c27ed 100644
--- a/components/dfs/dfs_v1/filesystems/romfs/dfs_romfs.c
+++ b/components/dfs/dfs_v1/filesystems/romfs/dfs_romfs.c
@@ -337,7 +337,7 @@ int dfs_romfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t coun
RT_ASSERT(len <= RT_UINT8_MAX);
d->d_namlen = (rt_uint8_t)len;
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
- rt_strncpy(d->d_name, name, DFS_PATH_MAX);
+ rt_strncpy(d->d_name, name, DIRENT_NAME_MAX);
/* move to next position */
++ file->pos;
diff --git a/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c b/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c
index 5766d7cbe7..5ea5140fc1 100644
--- a/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c
+++ b/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c
@@ -742,7 +742,7 @@ int dfs_elm_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
d->d_namlen = (rt_uint8_t)rt_strlen(fn);
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
- rt_strncpy(d->d_name, fn, DFS_PATH_MAX);
+ rt_strncpy(d->d_name, fn, DIRENT_NAME_MAX);
index ++;
if (index * sizeof(struct dirent) >= count)
diff --git a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c
index 36d1ea692b..f289fc4419 100644
--- a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c
+++ b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c
@@ -589,7 +589,8 @@ static int dfs_tmpfs_rename(struct dfs_dentry *old_dentry, struct dfs_dentry *ne
struct tmpfs_file *d_file, *p_file;
struct tmpfs_sb *superblock;
rt_size_t size;
- char parent_path[DFS_PATH_MAX], file_name[TMPFS_NAME_MAX];
+ char *parent_path;
+ char file_name[TMPFS_NAME_MAX];
superblock = (struct tmpfs_sb *)old_dentry->mnt->data;
RT_ASSERT(superblock != NULL);
@@ -602,10 +603,19 @@ static int dfs_tmpfs_rename(struct dfs_dentry *old_dentry, struct dfs_dentry *ne
if (d_file == NULL)
return -ENOENT;
+ parent_path = rt_malloc(DFS_PATH_MAX);
+ if (!parent_path)
+ {
+ return -ENOMEM;
+ }
+
/* find parent file */
_path_separate(new_dentry->pathname, parent_path, file_name);
if (file_name[0] == '\0') /* it's root dir */
+ {
+ rt_free(parent_path);
return -ENOENT;
+ }
/* open parent directory */
p_file = dfs_tmpfs_lookup(superblock, parent_path, &size);
RT_ASSERT(p_file != NULL);
@@ -620,6 +630,8 @@ static int dfs_tmpfs_rename(struct dfs_dentry *old_dentry, struct dfs_dentry *ne
rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling));
rt_spin_unlock(&superblock->lock);
+ rt_free(parent_path);
+
return RT_EOK;
}
@@ -672,7 +684,8 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t
rt_size_t size;
struct tmpfs_sb *superblock;
struct tmpfs_file *d_file, *p_file;
- char parent_path[DFS_PATH_MAX], file_name[TMPFS_NAME_MAX];
+ char *parent_path;
+ char file_name[TMPFS_NAME_MAX];
if (dentry == NULL || dentry->mnt == NULL || dentry->mnt->data == NULL)
{
@@ -682,6 +695,12 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t
superblock = (struct tmpfs_sb *)dentry->mnt->data;
RT_ASSERT(superblock != NULL);
+ parent_path = rt_malloc(DFS_PATH_MAX);
+ if (!parent_path)
+ {
+ return NULL;
+ }
+
vnode = dfs_vnode_create();
if (vnode)
{
@@ -689,6 +708,7 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t
_path_separate(dentry->pathname, parent_path, file_name);
if (file_name[0] == '\0') /* it's root dir */
{
+ rt_free(parent_path);
dfs_vnode_destroy(vnode);
return NULL;
}
@@ -697,6 +717,7 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t
p_file = dfs_tmpfs_lookup(superblock, parent_path, &size);
if (p_file == NULL)
{
+ rt_free(parent_path);
dfs_vnode_destroy(vnode);
return NULL;
}
@@ -705,6 +726,7 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t
d_file = (struct tmpfs_file *)rt_calloc(1, sizeof(struct tmpfs_file));
if (d_file == NULL)
{
+ rt_free(parent_path);
dfs_vnode_destroy(vnode);
return NULL;
}
@@ -743,6 +765,8 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t
vnode->size = d_file->size;
}
+ rt_free(parent_path);
+
return vnode;
}
diff --git a/components/dfs/dfs_v2/include/dfs.h b/components/dfs/dfs_v2/include/dfs.h
index 61c78b62a5..aa3bd84f27 100644
--- a/components/dfs/dfs_v2/include/dfs.h
+++ b/components/dfs/dfs_v2/include/dfs.h
@@ -53,15 +53,15 @@
* skip stdin/stdout/stderr normally
*/
#ifndef DFS_STDIO_OFFSET
-#define DFS_STDIO_OFFSET 3
+#define DFS_STDIO_OFFSET 3
#endif
#ifndef DFS_PATH_MAX
-#define DFS_PATH_MAX DIRENT_NAME_MAX
+#define DFS_PATH_MAX 4096
#endif
#ifndef SECTOR_SIZE
-#define SECTOR_SIZE 512
+#define SECTOR_SIZE 512
#endif
#define DFS_FS_FLAG_DEFAULT 0x00 /* default flag */
diff --git a/components/dfs/dfs_v2/src/dfs.c b/components/dfs/dfs_v2/src/dfs.c
index 04f2657d65..06d353c180 100644
--- a/components/dfs/dfs_v2/src/dfs.c
+++ b/components/dfs/dfs_v2/src/dfs.c
@@ -583,10 +583,19 @@ char *dfs_normalize_path(const char *directory, const char *filename)
if (filename[0] != '/') /* it's a absolute path, use it directly */
{
- fullpath = (char *)rt_malloc(strlen(directory) + strlen(filename) + 2);
+ int path_len;
+ path_len = strlen(directory) + strlen(filename) + 2;
+ if (path_len > DFS_PATH_MAX)
+ {
+ return NULL;
+ }
+
+ fullpath = (char *)rt_malloc(path_len);
if (fullpath == NULL)
+ {
return NULL;
+ }
/* join path and file name */
rt_snprintf(fullpath, strlen(directory) + strlen(filename) + 2,
diff --git a/components/dfs/dfs_v2/src/dfs_file.c b/components/dfs/dfs_v2/src/dfs_file.c
index 7e7df1738d..4bb933a32d 100644
--- a/components/dfs/dfs_v2/src/dfs_file.c
+++ b/components/dfs/dfs_v2/src/dfs_file.c
@@ -27,9 +27,24 @@
#define DBG_LVL DBG_WARNING
#include <rtdbg.h>
-
#define MAX_RW_COUNT 0xfffc0000
+rt_inline int _find_path_node(const char *path)
+{
+ int i = 0;
+
+ while (path[i] != '\0')
+ {
+ if ('/' == path[i++])
+ {
+ break;
+ }
+ }
+
+ /* return path-note length */
+ return i;
+}
+
/*
* rw_verify_area doesn't like huge counts. We limit
* them to something that fits in "int" so that others
@@ -143,7 +158,7 @@ struct dfs_dentry* dfs_file_follow_link(struct dfs_dentry *dentry)
{
char *buf = NULL;
- buf = (char *) rt_malloc (DFS_PATH_MAX);
+ buf = (char *)rt_malloc(DFS_PATH_MAX);
if (buf)
{
do
@@ -211,130 +226,83 @@ char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode)
{
int index = 0;
char *path = RT_NULL;
- char link_fn[DFS_PATH_MAX] = {0};
+ char *link_fn;
struct dfs_dentry *dentry = RT_NULL;
- path = (char *)rt_malloc((DFS_PATH_MAX * 2) + 1); // path + syslink + \0
+ path = (char *)rt_malloc((DFS_PATH_MAX * 2) + 2); // path + \0 + link_fn + \0
if (!path)
{
return path;
}
+ link_fn = path + DFS_PATH_MAX + 1;
if (*mnt && fullpath)
{
int i = 0;
char *fp = fullpath;
- while (*fp != '\0')
+ while ((i = _find_path_node(fp)) > 0)
{
- fp++;
- i++;
- if (*fp == '/')
+ if (i + index > DFS_PATH_MAX)
{
- rt_memcpy(path + index, fp - i, i);
- path[index + i] = '\0';
-
- dentry = dfs_dentry_lookup(*mnt, path, 0);
- if (dentry && dentry->vnode->type == FT_SYMLINK)
- {
- int ret = -1;
-
- if ((*mnt)->fs_ops->readlink)
- {
- if (dfs_is_mounted((*mnt)) == 0)
- {
- ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX);
- }
- }
-
- if (ret > 0)
- {
- int len = rt_strlen(link_fn);
- if (link_fn[0] == '/')
- {
- rt_memcpy(path, link_fn, len);
- index = len;
- }
- else
- {
- path[index] = '/';
- index++;
- rt_memcpy(path + index, link_fn, len);
- index += len;
- }
- path[index] = '\0';
- *mnt = dfs_mnt_lookup(path);
- }
- else
- {
- rt_kprintf("link error: %s\n", path);
- }
- }
- else
- {
- index += i;
- }
- dfs_dentry_unref(dentry);
- i = 0;
+ goto _ERR_RET;
}
- }
- if (i)
- {
- rt_memcpy(path + index, fp - i, i);
+ rt_memcpy(path + index, fp, i);
path[index + i] = '\0';
+ fp += i;
- if (mode)
+ dentry = dfs_dentry_lookup(*mnt, path, 0);
+ if (dentry && dentry->vnode->type == FT_SYMLINK)
{
- dentry = dfs_dentry_lookup(*mnt, path, 0);
- if (dentry && dentry->vnode->type == FT_SYMLINK)
- {
- int ret = -1;
+ int ret = -1;
- if ((*mnt)->fs_ops->readlink)
+ if ((*mnt)->fs_ops->readlink)
+ {
+ if (dfs_is_mounted((*mnt)) == 0)
{
- if (dfs_is_mounted((*mnt)) == 0)
- {
- ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX);
- }
+ ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX);
}
+ }
+
+ if (ret > 0)
+ {
+ int len = rt_strlen(link_fn);
- if (ret > 0)
+ if (link_fn[0] != '/')
{
- int len = rt_strlen(link_fn);
- if (link_fn[0] == '/')
- {
- rt_memcpy(path, link_fn, len);
- index = len;
- }
- else
- {
- path[index] = '/';
- index++;
- rt_memcpy(path + index, link_fn, len);
- index += len;
- }
- path[index] = '\0';
- *mnt = dfs_mnt_lookup(path);
+ path[index] = '/';
}
else
{
- rt_kprintf("link error: %s\n", path);
+ index = 0;
}
- char *_fullpath = dfs_normalize_path(RT_NULL, path);
- if (_fullpath)
+ if (len + index + 1 >= DFS_PATH_MAX)
{
- strncpy(path, _fullpath, DFS_PATH_MAX);
- rt_free(_fullpath);
+ goto _ERR_RET;
}
+
+ rt_memcpy(path + index, link_fn, len);
+ index += len;
+ path[index] = '\0';
+ *mnt = dfs_mnt_lookup(path);
+ }
+ else
+ {
+ goto _ERR_RET;
}
- dfs_dentry_unref(dentry);
}
+ else
+ {
+ index += i;
+ }
+ dfs_dentry_unref(dentry);
}
}
else
{
+_ERR_RET:
rt_free(path);
path = RT_NULL;
}
@@ -1837,7 +1805,7 @@ void ls(const char *pathname)
DLOG(msg, "dfs", "dfs_file", DLOG_MSG, "dfs_file_open(%s, O_DIRECTORY, 0)", path);
if (dfs_file_open(&file, path, O_DIRECTORY, 0) >= 0)
{
- char *link_fn = (char *) rt_malloc (DFS_PATH_MAX);
+ char *link_fn = (char *)rt_malloc(DFS_PATH_MAX);
if (link_fn)
{
rt_kprintf("Directory %s:\n", path);
diff --git a/components/finsh/msh_file.c b/components/finsh/msh_file.c
index a47ae73f05..ce24768bdf 100644
--- a/components/finsh/msh_file.c
+++ b/components/finsh/msh_file.c
@@ -343,6 +343,11 @@ static void directory_delete_for_msh(const char *pathname, char f, char v)
if (rt_strcmp(".", dirent->d_name) != 0 &&
rt_strcmp("..", dirent->d_name) != 0)
{
+ if (strlen(pathname) + 1 + strlen(dirent->d_name) > DFS_PATH_MAX)
+ {
+ rt_kprintf("cannot remove '%s/%s', path too long.\n", pathname, dirent->d_name);
+ continue;
+ }
rt_sprintf(full_path, "%s/%s", pathname, dirent->d_name);
if (dirent->d_type != DT_DIR)
{
@@ -862,6 +867,11 @@ static void directory_setattr(const char *pathname, struct dfs_attr *attr, char
if (rt_strcmp(".", dirent->d_name) != 0 &&
rt_strcmp("..", dirent->d_name) != 0)
{
+ if (strlen(pathname) + 1 + strlen(dirent->d_name) > DFS_PATH_MAX)
+ {
+ rt_kprintf("'%s/%s' setattr failed, path too long.\n", pathname, dirent->d_name);
+ continue;
+ }
rt_sprintf(full_path, "%s/%s", pathname, dirent->d_name);
if (dirent->d_type == DT_REG)
{
diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c
index 90d116db5c..d2177539df 100644
--- a/components/lwp/lwp_syscall.c
+++ b/components/lwp/lwp_syscall.c
@@ -4874,7 +4874,7 @@ struct libc_dirent {
off_t d_off;
unsigned short d_reclen;
unsigned char d_type;
- char d_name[256];
+ char d_name[DIRENT_NAME_MAX];
};
sysret_t sys_getdents(int fd, struct libc_dirent *dirp, size_t nbytes)