Skip to content

Commit 083e4e7

Browse files
committed
[FIX][DFS]参考V1版本,修复V2版本的ramfs与tmpfs路径名处理边界问题
1 parent 63b4a7f commit 083e4e7

2 files changed

Lines changed: 109 additions & 19 deletions

File tree

components/dfs/dfs_v2/filesystems/ramfs/dfs_ramfs.c

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,51 @@ int dfs_ramfs_ioctl(struct dfs_file *file, int cmd, void *args)
5959
return -EIO;
6060
}
6161

62+
static int _ramfs_set_name(char *name, rt_size_t name_size, const char *path)
63+
{
64+
const char *name_ptr = path;
65+
const char *name_scan;
66+
rt_size_t name_len;
67+
68+
if (path == RT_NULL)
69+
{
70+
return -EINVAL;
71+
}
72+
73+
/* strip leading '/' */
74+
while (*name_ptr == '/' && *name_ptr)
75+
{
76+
name_ptr++;
77+
}
78+
79+
if (*name_ptr == '\0')
80+
{
81+
return -ENOENT;
82+
}
83+
84+
/* reject multi-level paths (ramfs is flat) */
85+
name_scan = name_ptr;
86+
while (*name_scan)
87+
{
88+
if (*name_scan == '/')
89+
{
90+
return -EINVAL;
91+
}
92+
name_scan++;
93+
}
94+
95+
name_len = rt_strlen(name_ptr);
96+
if (name_len >= name_size)
97+
{
98+
return -ENAMETOOLONG;
99+
}
100+
101+
rt_memcpy(name, name_ptr, name_len);
102+
name[name_len] = '\0';
103+
104+
return RT_EOK;
105+
}
106+
62107
struct ramfs_dirent *dfs_ramfs_lookup(struct dfs_ramfs *ramfs,
63108
const char *path,
64109
rt_size_t *size)
@@ -232,7 +277,7 @@ int dfs_ramfs_open(struct dfs_file *file)
232277
{
233278
if (file->flags & O_CREAT || file->flags & O_WRONLY)
234279
{
235-
char *name_ptr;
280+
int ret;
236281

237282
/* create a file entry */
238283
dirent = (struct ramfs_dirent *)
@@ -243,13 +288,12 @@ int dfs_ramfs_open(struct dfs_file *file)
243288
return -ENOMEM;
244289
}
245290

246-
/* remove '/' separator */
247-
name_ptr = file->vnode->path;
248-
while (*name_ptr == '/' && *name_ptr)
291+
ret = _ramfs_set_name(dirent->name, sizeof(dirent->name), file->vnode->path);
292+
if (ret != RT_EOK)
249293
{
250-
name_ptr++;
294+
rt_memheap_free(dirent);
295+
return ret;
251296
}
252-
strncpy(dirent->name, name_ptr, RAMFS_NAME_MAX);
253297

254298
rt_list_init(&(dirent->list));
255299
dirent->data = NULL;
@@ -390,6 +434,7 @@ int dfs_ramfs_rename(struct dfs_filesystem *fs,
390434
struct ramfs_dirent *dirent;
391435
struct dfs_ramfs *ramfs;
392436
rt_size_t size;
437+
int ret;
393438

394439
ramfs = (struct dfs_ramfs *)fs->data;
395440
RT_ASSERT(ramfs != NULL);
@@ -402,7 +447,11 @@ int dfs_ramfs_rename(struct dfs_filesystem *fs,
402447
if (dirent == NULL)
403448
return -ENOENT;
404449

405-
strncpy(dirent->name, newpath, RAMFS_NAME_MAX);
450+
ret = _ramfs_set_name(dirent->name, sizeof(dirent->name), newpath);
451+
if (ret != RT_EOK)
452+
{
453+
return ret;
454+
}
406455

407456
return RT_EOK;
408457
}
@@ -471,7 +520,7 @@ struct dfs_ramfs *dfs_ramfs_create(rt_uint8_t *pool, rt_size_t size)
471520
rt_memset(&(ramfs->root), 0x00, sizeof(ramfs->root));
472521
rt_list_init(&(ramfs->root.list));
473522
ramfs->root.size = 0;
474-
strcpy(ramfs->root.name, ".");
523+
rt_strcpy(ramfs->root.name, ".");
475524
ramfs->root.fs = ramfs;
476525

477526
return ramfs;

components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,16 @@ static struct dfs_aspace_ops dfs_tmp_aspace_ops =
4343
};
4444
#endif
4545

46-
static int _path_separate(const char *path, char *parent_path, char *file_name)
46+
static int _path_separate(const char *path, char *parent_path, rt_size_t parent_size,
47+
char *file_name, rt_size_t file_size)
4748
{
4849
const char *path_p, *path_q;
50+
rt_size_t parent_len, file_len;
4951

5052
RT_ASSERT(path[0] == '/');
5153

5254
file_name[0] = '\0';
55+
parent_path[0] = '\0';
5356
path_p = path_q = &path[1];
5457
__next_dir:
5558
while (*path_q != '/' && *path_q != '\0')
@@ -66,10 +69,18 @@ static int _path_separate(const char *path, char *parent_path, char *file_name)
6669
}
6770
else /* Last level dir */
6871
{
69-
rt_memcpy(parent_path, path, path_p - path - 1);
70-
parent_path[path_p - path - 1] = '\0';
71-
rt_memcpy(file_name, path_p, path_q - path_p);
72-
file_name[path_q - path_p] = '\0';
72+
parent_len = path_p - path - 1;
73+
file_len = path_q - path_p;
74+
75+
if ((parent_len + 1 > parent_size) || (file_len + 1 > file_size))
76+
{
77+
return -ENAMETOOLONG;
78+
}
79+
80+
rt_memcpy(parent_path, path, parent_len);
81+
parent_path[parent_len] = '\0';
82+
rt_memcpy(file_name, path_p, file_len);
83+
file_name[file_len] = '\0';
7384
}
7485
}
7586
if (parent_path[0] == 0)
@@ -83,17 +94,31 @@ static int _path_separate(const char *path, char *parent_path, char *file_name)
8394
return 0;
8495
}
8596

86-
static int _get_subdir(const char *path, char *name)
97+
static int _get_subdir(const char *path, char *name, rt_size_t name_size)
8798
{
8899
const char *subpath = path;
100+
rt_size_t len = 0;
101+
102+
if (name_size == 0)
103+
{
104+
return -EINVAL;
105+
}
106+
89107
while (*subpath == '/' && *subpath)
90108
subpath ++;
91109
while (*subpath != '/' && *subpath)
92110
{
111+
if (len + 1 >= name_size)
112+
{
113+
name[0] = '\0';
114+
return -ENAMETOOLONG;
115+
}
93116
*name = *subpath;
94117
name ++;
95118
subpath ++;
119+
len ++;
96120
}
121+
*name = '\0';
97122
return 0;
98123
}
99124

@@ -256,7 +281,10 @@ struct tmpfs_file *dfs_tmpfs_lookup(struct tmpfs_sb *superblock,
256281
subpath ++; /* skip '/' */
257282

258283
memset(subdir_name, 0, TMPFS_NAME_MAX);
259-
_get_subdir(curpath, subdir_name);
284+
if (_get_subdir(curpath, subdir_name, sizeof(subdir_name)) != 0)
285+
{
286+
return RT_NULL;
287+
}
260288

261289
rt_spin_lock(&superblock->lock);
262290

@@ -612,7 +640,12 @@ static int dfs_tmpfs_rename(struct dfs_dentry *old_dentry, struct dfs_dentry *ne
612640
}
613641

614642
/* find parent file */
615-
_path_separate(new_dentry->pathname, parent_path, file_name);
643+
if (_path_separate(new_dentry->pathname, parent_path, DFS_PATH_MAX,
644+
file_name, sizeof(file_name)) != RT_EOK)
645+
{
646+
rt_free(parent_path);
647+
return -ENAMETOOLONG;
648+
}
616649
if (file_name[0] == '\0') /* it's root dir */
617650
{
618651
rt_free(parent_path);
@@ -626,7 +659,8 @@ static int dfs_tmpfs_rename(struct dfs_dentry *old_dentry, struct dfs_dentry *ne
626659
dfs_vfs_remove_node(&d_file->node);
627660
rt_spin_unlock(&superblock->lock);
628661

629-
strncpy(d_file->name, file_name, TMPFS_NAME_MAX);
662+
rt_strncpy(d_file->name, file_name, TMPFS_NAME_MAX);
663+
d_file->name[TMPFS_NAME_MAX - 1] = '\0';
630664

631665
rt_spin_lock(&superblock->lock);
632666
dfs_vfs_append_node(&p_file->node, &d_file->node);
@@ -707,7 +741,13 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t
707741
if (vnode)
708742
{
709743
/* find parent file */
710-
_path_separate(dentry->pathname, parent_path, file_name);
744+
if (_path_separate(dentry->pathname, parent_path, DFS_PATH_MAX,
745+
file_name, sizeof(file_name)) != RT_EOK)
746+
{
747+
rt_free(parent_path);
748+
dfs_vnode_destroy(vnode);
749+
return NULL;
750+
}
711751
if (file_name[0] == '\0') /* it's root dir */
712752
{
713753
rt_free(parent_path);
@@ -735,7 +775,8 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t
735775

736776
superblock->df_size += sizeof(struct tmpfs_file);
737777

738-
strncpy(d_file->name, file_name, TMPFS_NAME_MAX);
778+
rt_strncpy(d_file->name, file_name, TMPFS_NAME_MAX);
779+
d_file->name[TMPFS_NAME_MAX - 1] = '\0';
739780

740781
dfs_vfs_init_node(&d_file->node);
741782
d_file->data = NULL;

0 commit comments

Comments
 (0)