fix dfs path name overflow. (#8305)
This commit is contained in:
parent
249871cbbc
commit
74925f43ed
|
@ -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!
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
if (fullpath == NULL)
|
||||
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,
|
||||
|
|
|
@ -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';
|
||||
goto _ERR_RET;
|
||||
}
|
||||
|
||||
dentry = dfs_dentry_lookup(*mnt, path, 0);
|
||||
if (dentry && dentry->vnode->type == FT_SYMLINK)
|
||||
rt_memcpy(path + index, fp, i);
|
||||
path[index + i] = '\0';
|
||||
fp += i;
|
||||
|
||||
dentry = dfs_dentry_lookup(*mnt, path, 0);
|
||||
if (dentry && dentry->vnode->type == FT_SYMLINK)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if ((*mnt)->fs_ops->readlink)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
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)
|
||||
if (ret > 0)
|
||||
{
|
||||
int len = rt_strlen(link_fn);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (len + index + 1 >= DFS_PATH_MAX)
|
||||
{
|
||||
goto _ERR_RET;
|
||||
}
|
||||
|
||||
rt_memcpy(path + index, link_fn, len);
|
||||
index += len;
|
||||
path[index] = '\0';
|
||||
*mnt = dfs_mnt_lookup(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
index += i;
|
||||
goto _ERR_RET;
|
||||
}
|
||||
dfs_dentry_unref(dentry);
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
rt_memcpy(path + index, fp - i, i);
|
||||
path[index + i] = '\0';
|
||||
|
||||
if (mode)
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
char *_fullpath = dfs_normalize_path(RT_NULL, path);
|
||||
if (_fullpath)
|
||||
{
|
||||
strncpy(path, _fullpath, DFS_PATH_MAX);
|
||||
rt_free(_fullpath);
|
||||
}
|
||||
}
|
||||
dfs_dentry_unref(dentry);
|
||||
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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue