2626#define DBG_LVL DBG_INFO
2727#include <rtdbg.h>
2828
29- static int _path_separate (const char * path , char * parent_path , char * file_name )
29+ static int _tmpfs_path_validate (const char * path )
30+ {
31+ if (path == RT_NULL )
32+ {
33+ return - EINVAL ;
34+ }
35+
36+ if (path [0 ] != '/' )
37+ {
38+ return - EINVAL ;
39+ }
40+
41+ return RT_EOK ;
42+ }
43+
44+ static int _path_separate (const char * path , char * parent_path , rt_size_t parent_size ,
45+ char * file_name , rt_size_t file_size )
3046{
3147 const char * path_p , * path_q ;
48+ rt_size_t parent_len , file_len ;
49+ int ret ;
3250
33- RT_ASSERT (path [0 ] == '/' );
51+ ret = _tmpfs_path_validate (path );
52+ if (ret != RT_EOK )
53+ {
54+ return ret ;
55+ }
3456
3557 file_name [0 ] = '\0' ;
58+ parent_path [0 ] = '\0' ;
3659 path_p = path_q = & path [1 ];
3760__next_dir :
3861 while (* path_q != '/' && * path_q != '\0' )
@@ -49,10 +72,18 @@ static int _path_separate(const char *path, char *parent_path, char *file_name)
4972 }
5073 else /* Last level dir */
5174 {
52- rt_memcpy (parent_path , path , path_p - path - 1 );
53- parent_path [path_p - path - 1 ] = '\0' ;
54- rt_memcpy (file_name , path_p , path_q - path_p );
55- file_name [path_q - path_p ] = '\0' ;
75+ parent_len = path_p - path - 1 ;
76+ file_len = path_q - path_p ;
77+
78+ if ((parent_len + 1 > parent_size ) || (file_len + 1 > file_size ))
79+ {
80+ return - ENAMETOOLONG ;
81+ }
82+
83+ rt_memcpy (parent_path , path , parent_len );
84+ parent_path [parent_len ] = '\0' ;
85+ rt_memcpy (file_name , path_p , file_len );
86+ file_name [file_len ] = '\0' ;
5687 }
5788 }
5889 if (parent_path [0 ] == 0 )
@@ -66,17 +97,31 @@ static int _path_separate(const char *path, char *parent_path, char *file_name)
6697 return 0 ;
6798}
6899
69- static int _get_subdir (const char * path , char * name )
100+ static int _get_subdir (const char * path , char * name , rt_size_t name_size )
70101{
71102 const char * subpath = path ;
103+ rt_size_t name_len = 0 ;
104+
105+ if (name_size == 0 )
106+ {
107+ return - EINVAL ;
108+ }
109+
72110 while (* subpath == '/' && * subpath )
73111 subpath ++ ;
74112 while (* subpath != '/' && * subpath )
75113 {
114+ if (name_len + 1 >= name_size )
115+ {
116+ name [0 ] = '\0' ;
117+ return - ENAMETOOLONG ;
118+ }
76119 * name = * subpath ;
77120 name ++ ;
78121 subpath ++ ;
122+ name_len ++ ;
79123 }
124+ * name = '\0' ;
80125 return 0 ;
81126}
82127
@@ -222,6 +267,13 @@ struct tmpfs_file *dfs_tmpfs_lookup(struct tmpfs_sb *superblock,
222267 char subdir_name [TMPFS_NAME_MAX ];
223268 struct tmpfs_file * file , * curfile ;
224269 rt_list_t * list ;
270+ int ret ;
271+
272+ ret = _tmpfs_path_validate (path );
273+ if (ret != RT_EOK )
274+ {
275+ return RT_NULL ;
276+ }
225277
226278 subpath = path ;
227279 while (* subpath == '/' && * subpath )
@@ -245,7 +297,10 @@ struct tmpfs_file *dfs_tmpfs_lookup(struct tmpfs_sb *superblock,
245297 subpath ++ ; /* skip '/' */
246298
247299 memset (subdir_name , 0 , TMPFS_NAME_MAX );
248- _get_subdir (curpath , subdir_name );
300+ if (_get_subdir (curpath , subdir_name , sizeof (subdir_name )) != 0 )
301+ {
302+ return RT_NULL ;
303+ }
249304
250305 rt_spin_lock (& superblock -> lock );
251306
@@ -364,6 +419,7 @@ int dfs_tmpfs_close(struct dfs_file *file)
364419
365420int dfs_tmpfs_open (struct dfs_file * file )
366421{
422+ int ret ;
367423 rt_size_t size ;
368424 struct tmpfs_sb * superblock ;
369425 struct tmpfs_file * d_file , * p_file ;
@@ -387,6 +443,12 @@ int dfs_tmpfs_open(struct dfs_file *file)
387443 superblock = (struct tmpfs_sb * )fs -> data ;
388444 RT_ASSERT (superblock != NULL );
389445
446+ ret = _tmpfs_path_validate (file -> vnode -> path );
447+ if (ret != RT_EOK )
448+ {
449+ return ret ;
450+ }
451+
390452 /* find file */
391453 d_file = dfs_tmpfs_lookup (superblock , file -> vnode -> path , & size );
392454 if (d_file == NULL && !(file -> flags & O_CREAT ))
@@ -398,7 +460,12 @@ int dfs_tmpfs_open(struct dfs_file *file)
398460 if (d_file == NULL )
399461 {
400462 /* find parent file */
401- _path_separate (file -> vnode -> path , parent_path , file_name );
463+ ret = _path_separate (file -> vnode -> path , parent_path , sizeof (parent_path ),
464+ file_name , sizeof (file_name ));
465+ if (ret != RT_EOK )
466+ {
467+ return ret ;
468+ }
402469 if (file_name [0 ] == '\0' ) /* it's root dir */
403470 return - ENOENT ;
404471
@@ -415,7 +482,8 @@ int dfs_tmpfs_open(struct dfs_file *file)
415482 }
416483 superblock -> df_size += sizeof (struct tmpfs_file );
417484
418- strncpy (d_file -> name , file_name , TMPFS_NAME_MAX );
485+ rt_strncpy (d_file -> name , file_name , TMPFS_NAME_MAX );
486+ d_file -> name [TMPFS_NAME_MAX - 1 ] = '\0' ;
419487
420488 rt_list_init (& (d_file -> subdirs ));
421489 rt_list_init (& (d_file -> sibling ));
@@ -592,6 +660,7 @@ int dfs_tmpfs_rename(struct dfs_filesystem *fs,
592660 const char * oldpath ,
593661 const char * newpath )
594662{
663+ int ret ;
595664 struct tmpfs_file * d_file , * p_file ;
596665 struct tmpfs_sb * superblock ;
597666 rt_size_t size ;
@@ -600,6 +669,18 @@ int dfs_tmpfs_rename(struct dfs_filesystem *fs,
600669 superblock = (struct tmpfs_sb * )fs -> data ;
601670 RT_ASSERT (superblock != NULL );
602671
672+ ret = _tmpfs_path_validate (newpath );
673+ if (ret != RT_EOK )
674+ {
675+ return ret ;
676+ }
677+
678+ ret = _tmpfs_path_validate (oldpath );
679+ if (ret != RT_EOK )
680+ {
681+ return ret ;
682+ }
683+
603684 d_file = dfs_tmpfs_lookup (superblock , newpath , & size );
604685 if (d_file != NULL )
605686 return - EEXIST ;
@@ -609,7 +690,12 @@ int dfs_tmpfs_rename(struct dfs_filesystem *fs,
609690 return - ENOENT ;
610691
611692 /* find parent file */
612- _path_separate (newpath , parent_path , file_name );
693+ ret = _path_separate (newpath , parent_path , sizeof (parent_path ),
694+ file_name , sizeof (file_name ));
695+ if (ret != RT_EOK )
696+ {
697+ return ret ;
698+ }
613699 if (file_name [0 ] == '\0' ) /* it's root dir */
614700 return - ENOENT ;
615701 /* open parent directory */
@@ -620,7 +706,8 @@ int dfs_tmpfs_rename(struct dfs_filesystem *fs,
620706 rt_list_remove (& (d_file -> sibling ));
621707 rt_spin_unlock (& superblock -> lock );
622708
623- strncpy (d_file -> name , file_name , TMPFS_NAME_MAX );
709+ rt_strncpy (d_file -> name , file_name , TMPFS_NAME_MAX );
710+ d_file -> name [TMPFS_NAME_MAX - 1 ] = '\0' ;
624711
625712 rt_spin_lock (& superblock -> lock );
626713 rt_list_insert_after (& (p_file -> subdirs ), & (d_file -> sibling ));
0 commit comments