Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 78 additions & 47 deletions components/dfs/dfs_v1/filesystems/cromfs/dfs_cromfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@
#define CROMFS_PATITION_HEAD_SIZE 256
#define CROMFS_DIRENT_CACHE_SIZE 8

#define CROMFS_MAGIC "CROMFSMG"
#define CROMFS_MAGIC "CROMFSMG"

#define CROMFS_CT_ASSERT(name, x) \
struct assert_##name {char ary[2 * (x) - 1];}
struct assert_##name \
{ \
char ary[2 * (x) - 1]; \
}

#define CROMFS_POS_ROOT (0x0UL)
#define CROMFS_POS_ERROR (0x1UL)
Expand Down Expand Up @@ -58,7 +61,7 @@ typedef struct
uint32_t file_size; /* file data size */
uint32_t file_origin_size; /* file size before compress */
uint32_t parition_pos; /* offset of data */
uint8_t name[0]; /* name data */
uint8_t name[0]; /* name data */
} cromfs_dirent;

#define CROMFS_ALIGN_SIZE_BIT 4
Expand Down Expand Up @@ -109,27 +112,27 @@ typedef struct

/**********************************/

#define avl_key_t uint32_t
#define AVL_EMPTY (struct cromfs_avl_struct *)0
#define avl_maxheight 32
#define heightof(tree) ((tree) == AVL_EMPTY ? 0 : (tree)->avl_height)
#define avl_key_t uint32_t
#define AVL_EMPTY (struct cromfs_avl_struct *)0
#define avl_maxheight 32
#define heightof(tree) ((tree) == AVL_EMPTY ? 0 : (tree)->avl_height)

struct cromfs_avl_struct
{
struct cromfs_avl_struct *avl_left;
struct cromfs_avl_struct *avl_right;
int avl_height;
int avl_height;
avl_key_t avl_key;
file_info *fi;
};

static void cromfs_avl_remove(struct cromfs_avl_struct *node_to_delete, struct cromfs_avl_struct **ptree);
static void cromfs_avl_insert(struct cromfs_avl_struct *new_node, struct cromfs_avl_struct **ptree);
static struct cromfs_avl_struct* cromfs_avl_find(avl_key_t key, struct cromfs_avl_struct *ptree);
static struct cromfs_avl_struct *cromfs_avl_find(avl_key_t key, struct cromfs_avl_struct *ptree);

static void cromfs_avl_rebalance(struct cromfs_avl_struct ***nodeplaces_ptr, int count)
{
for (;count > 0; count--)
for (; count > 0; count--)
{
struct cromfs_avl_struct **nodeplace = *--nodeplaces_ptr;
struct cromfs_avl_struct *node = *nodeplace;
Expand All @@ -139,8 +142,8 @@ static void cromfs_avl_rebalance(struct cromfs_avl_struct ***nodeplaces_ptr, int
int heightright = heightof(noderight);
if (heightright + 1 < heightleft)
{
struct cromfs_avl_struct * nodeleftleft = nodeleft->avl_left;
struct cromfs_avl_struct * nodeleftright = nodeleft->avl_right;
struct cromfs_avl_struct *nodeleftleft = nodeleft->avl_left;
struct cromfs_avl_struct *nodeleftright = nodeleft->avl_right;
int heightleftright = heightof(nodeleftright);
if (heightof(nodeleftleft) >= heightleftright)
{
Expand Down Expand Up @@ -183,8 +186,9 @@ static void cromfs_avl_rebalance(struct cromfs_avl_struct ***nodeplaces_ptr, int
*nodeplace = noderightleft;
}
}
else {
int height = (heightleft<heightright ? heightright : heightleft) + 1;
else
{
int height = (heightleft < heightright ? heightright : heightleft) + 1;
if (height == node->avl_height)
{
break;
Expand Down Expand Up @@ -233,9 +237,9 @@ static void cromfs_avl_remove(struct cromfs_avl_struct *node_to_delete, struct c
}
else
{
struct cromfs_avl_struct *** stack_ptr_to_delete = stack_ptr;
struct cromfs_avl_struct ** nodeplace = &node_to_delete->avl_left;
struct cromfs_avl_struct * node;
struct cromfs_avl_struct ***stack_ptr_to_delete = stack_ptr;
struct cromfs_avl_struct **nodeplace = &node_to_delete->avl_left;
struct cromfs_avl_struct *node;
for (;;)
{
node = *nodeplace;
Expand All @@ -254,7 +258,7 @@ static void cromfs_avl_remove(struct cromfs_avl_struct *node_to_delete, struct c
*nodeplace_to_delete = node;
*stack_ptr_to_delete = &node->avl_left;
}
cromfs_avl_rebalance(stack_ptr,stack_count);
cromfs_avl_rebalance(stack_ptr, stack_count);
}

static void cromfs_avl_insert(struct cromfs_avl_struct *new_node, struct cromfs_avl_struct **ptree)
Expand All @@ -266,7 +270,7 @@ static void cromfs_avl_insert(struct cromfs_avl_struct *new_node, struct cromfs_
struct cromfs_avl_struct ***stack_ptr = &stack[0]; /* = &stack[stackcount] */
for (;;)
{
struct cromfs_avl_struct * node = *nodeplace;
struct cromfs_avl_struct *node = *nodeplace;
if (node == AVL_EMPTY)
{
break;
Expand All @@ -286,10 +290,10 @@ static void cromfs_avl_insert(struct cromfs_avl_struct *new_node, struct cromfs_
new_node->avl_right = AVL_EMPTY;
new_node->avl_height = 1;
*nodeplace = new_node;
cromfs_avl_rebalance(stack_ptr,stack_count);
cromfs_avl_rebalance(stack_ptr, stack_count);
}

static struct cromfs_avl_struct* cromfs_avl_find(avl_key_t key, struct cromfs_avl_struct* ptree)
static struct cromfs_avl_struct *cromfs_avl_find(avl_key_t key, struct cromfs_avl_struct *ptree)
{
for (;;)
{
Expand Down Expand Up @@ -387,7 +391,7 @@ static uint32_t cromfs_blk_read_bytes(cromfs_info *ci, uint32_t pos, void *buf,
start_blk++;
if (sector_nr)
{
ret_len = rt_device_read(ci->device, start_blk, (char*)buf + off_s, sector_nr);
ret_len = rt_device_read(ci->device, start_blk, (char *)buf + off_s, sector_nr);
if (ret_len != sector_nr)
{
goto end;
Expand All @@ -401,7 +405,7 @@ static uint32_t cromfs_blk_read_bytes(cromfs_info *ci, uint32_t pos, void *buf,
{
goto end;
}
memcpy((char*)buf + off_s, block_buff, size);
memcpy((char *)buf + off_s, block_buff, size);
}
ret = size_bak;
end:
Expand Down Expand Up @@ -509,7 +513,7 @@ static int dfs_cromfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, con

len = cromfs_read_bytes(ci, 0, &ci->part_info, sizeof ci->part_info);
if (len != sizeof ci->part_info ||
memcmp(ci->part_info.magic, CROMFS_MAGIC, sizeof ci->part_info.magic) != 0)
memcmp(ci->part_info.magic, CROMFS_MAGIC, sizeof ci->part_info.magic) != 0)
{
free(ci);
return -RT_ERROR;
Expand All @@ -533,7 +537,7 @@ static int dfs_cromfs_unmount(struct dfs_filesystem *fs)

ci = (cromfs_info *)fs->data;

result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
return -RT_ERROR;
Expand Down Expand Up @@ -569,7 +573,7 @@ static int dfs_cromfs_ioctl(struct dfs_file *file, int cmd, void *args)
return -EIO;
}

static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, uint32_t *size, uint32_t *osize)
static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int *is_dir, uint32_t *size, uint32_t *osize)
{
uint32_t cur_size = 0, cur_pos = 0, cur_osize = 0;
const char *subpath = NULL, *subpath_end = NULL;
Expand Down Expand Up @@ -664,12 +668,12 @@ static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, ui
return cur_pos;
}

static uint32_t dfs_cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, uint32_t *size, uint32_t *osize)
static uint32_t dfs_cromfs_lookup(cromfs_info *ci, const char *path, int *is_dir, uint32_t *size, uint32_t *osize)
{
rt_err_t result = RT_EOK;
uint32_t ret = 0;

result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
return CROMFS_POS_ERROR;
Expand Down Expand Up @@ -747,7 +751,7 @@ static int dfs_cromfs_read(struct dfs_file *file, void *buf, size_t count)
{
int fill_ret = 0;

result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
return 0;
Expand All @@ -765,15 +769,15 @@ static int dfs_cromfs_read(struct dfs_file *file, void *buf, size_t count)
{
void *di_mem = NULL;

result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
return 0;
}
di_mem = cromfs_dirent_cache_get(ci, fi->partition_pos, fi->size);
if (di_mem)
{
memcpy(buf, (char*)di_mem + file->pos, length);
memcpy(buf, (char *)di_mem + file->pos, length);
}
rt_mutex_release(&ci->lock);
if (!di_mem)
Expand All @@ -800,7 +804,7 @@ static int dfs_cromfs_lseek(struct dfs_file *file, off_t offset)

static file_info *get_file_info(cromfs_info *ci, uint32_t partition_pos, int inc_ref)
{
struct cromfs_avl_struct* node = cromfs_avl_find(partition_pos, ci->cromfs_avl_root);
struct cromfs_avl_struct *node = cromfs_avl_find(partition_pos, ci->cromfs_avl_root);

if (node)
{
Expand Down Expand Up @@ -870,7 +874,7 @@ static file_info *inset_file_info(cromfs_info *ci, uint32_t partition_pos, int i

static void deref_file_info(cromfs_info *ci, uint32_t partition_pos)
{
struct cromfs_avl_struct* node = cromfs_avl_find(partition_pos, ci->cromfs_avl_root);
struct cromfs_avl_struct *node = cromfs_avl_find(partition_pos, ci->cromfs_avl_root);
file_info *fi = NULL;

if (node)
Expand Down Expand Up @@ -907,7 +911,7 @@ static int dfs_cromfs_close(struct dfs_file *file)
fs = (struct dfs_filesystem *)file->vnode->fs;
ci = (cromfs_info *)fs->data;

result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
return -RT_ERROR;
Expand Down Expand Up @@ -937,8 +941,7 @@ static int dfs_cromfs_open(struct dfs_file *file)
RT_ASSERT(file->vnode->ref_count > 0);
if (file->vnode->ref_count > 1)
{
if (file->vnode->type == FT_DIRECTORY
&& !(file->flags & O_DIRECTORY))
if (file->vnode->type == FT_DIRECTORY && !(file->flags & O_DIRECTORY))
{
return -ENOENT;
}
Expand Down Expand Up @@ -977,7 +980,7 @@ static int dfs_cromfs_open(struct dfs_file *file)
file->vnode->type = FT_REGULAR;
}

result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
ret = -EINTR;
Expand Down Expand Up @@ -1029,7 +1032,7 @@ static int dfs_cromfs_stat(struct dfs_filesystem *fs, const char *path, struct s

st->st_dev = 0;
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
S_IWUSR | S_IWGRP | S_IWOTH;
S_IWUSR | S_IWGRP | S_IWOTH;

if (is_dir)
{
Expand Down Expand Up @@ -1074,7 +1077,7 @@ static int dfs_cromfs_getdents(struct dfs_file *file, struct dirent *dirp, uint3
return -ENOMEM;
}

result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
free(dirent);
Expand Down Expand Up @@ -1103,10 +1106,35 @@ static int dfs_cromfs_getdents(struct dfs_file *file, struct dirent *dirp, uint3
for (index = 0; index < count && file->pos < file->vnode->size; index++)
{
uint32_t name_size = 0;
uint32_t entry_name_size = 0;

d = dirp + index;

/* the entry header itself has to be inside the directory blob we loaded */
if (file->pos + sizeof(cromfs_dirent) > fi->size)
{
result = -EINVAL;
break;
}

sub_dirent = &dirent[file->pos >> CROMFS_ALIGN_SIZE_BIT];
name = sub_dirent->dirent.name;
entry_name_size = sub_dirent->dirent.name_size;

/* name_size comes straight from the image, so it has to be validated
* before it is used as a length:
* - d_name holds DIRENT_NAME_MAX bytes, the terminating NUL included;
* - the name must stay inside the directory blob that was just loaded.
* Without these checks a crafted image overflows d_name, and since ls()
* and readdir() keep the dirent on the stack, it overflows the stack of
* the thread listing the directory.
*/
if (entry_name_size >= DIRENT_NAME_MAX ||
file->pos + sizeof(cromfs_dirent) + entry_name_size > fi->size)
{
result = -EINVAL;
break;
}

/* fill dirent */
if (sub_dirent->dirent.attr == CROMFS_DIRENT_ATTR_DIR)
Expand All @@ -1118,23 +1146,27 @@ static int dfs_cromfs_getdents(struct dfs_file *file, struct dirent *dirp, uint3
d->d_type = DT_REG;
}

d->d_namlen = sub_dirent->dirent.name_size;
d->d_namlen = entry_name_size;
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
memcpy(d->d_name, (char *)name, sub_dirent->dirent.name_size);
d->d_name[sub_dirent->dirent.name_size] = '\0';
memcpy(d->d_name, (char *)name, entry_name_size);
d->d_name[entry_name_size] = '\0';

name_size = (sub_dirent->dirent.name_size + CROMFS_ALIGN_SIZE_MASK) & ~CROMFS_ALIGN_SIZE_MASK;
name_size = (entry_name_size + CROMFS_ALIGN_SIZE_MASK) & ~CROMFS_ALIGN_SIZE_MASK;
/* move to next position */
file->pos += (name_size + sizeof *sub_dirent);
}

free(dirent);

if (result != RT_EOK)
{
return result;
}

return index * sizeof(struct dirent);
}

static const struct dfs_file_ops _crom_fops =
{
static const struct dfs_file_ops _crom_fops = {
dfs_cromfs_open,
dfs_cromfs_close,
dfs_cromfs_ioctl,
Expand All @@ -1145,8 +1177,7 @@ static const struct dfs_file_ops _crom_fops =
dfs_cromfs_getdents,
};

static const struct dfs_filesystem_ops _cromfs =
{
static const struct dfs_filesystem_ops _cromfs = {
"crom",
DFS_FS_FLAG_DEFAULT,
&_crom_fops,
Expand Down
5 changes: 5 additions & 0 deletions components/dfs/dfs_v2/filesystems/cromfs/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,9 @@ CPPPATH = [cwd]

group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS','RT_USING_DFS_CROMFS'], CPPPATH = CPPPATH)

list = os.listdir(cwd)
for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
group = group + SConscript(os.path.join(item, 'SConscript'))

Return('group')
Loading