From e0ae9008ef8739c3a3ba7ffefc119d591a2d2553 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Wed, 11 May 2011 03:01:54 +0000 Subject: 2011-05-11 Chris Johns PR 1774/filesystem * libfs/src/imfs/imfs_eval.c: Updated to fix regressions found in the testsuite. --- cpukit/ChangeLog | 8 +- cpukit/libfs/src/imfs/imfs_eval.c | 179 +++++++++++++++++++++----------------- 2 files changed, 107 insertions(+), 80 deletions(-) (limited to 'cpukit') diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index 429ab47604..7c0394c8f5 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,9 @@ +2011-05-11 Chris Johns + + PR 1774/filesystem + * libfs/src/imfs/imfs_eval.c: Updated to fix regressions found in + the testsuite. + 2011-05-05 Ralf Corsépius * librpc/include/rpc/auth.h, librpc/include/rpc/auth_unix.h, @@ -48,7 +54,7 @@ 2011-04-16 Chris Johns PR 1774/filesystem - * libfs/src/imfs/imfs_eval.c: Fix the IMFS eval and eval for make + * libfs/src/imfs/imfs_eval.c: Fix the IMFS eval anda eval for make handlers to not inspect a mounted file sytems path. 2011-04-15 Sebastian Huber diff --git a/cpukit/libfs/src/imfs/imfs_eval.c b/cpukit/libfs/src/imfs/imfs_eval.c index 55d5f403cf..477c09c935 100644 --- a/cpukit/libfs/src/imfs/imfs_eval.c +++ b/cpukit/libfs/src/imfs/imfs_eval.c @@ -256,6 +256,22 @@ int IMFS_evaluate_link( return result; } +/* + * IMFS_skip_separator + * + * Skip the separator in the path. + */ +static void IMFS_skip_separator ( + const char *path, /* IN */ + size_t *len, /* IN/OUT */ + int *index /* IN/OUT */ +) +{ + while ( IMFS_is_separator( path[*index] ) && path[*index] && *len ) { + ++(*index); + --(*len); + } +} /* * IMFS_evaluate_for_make @@ -267,20 +283,19 @@ int IMFS_evaluate_link( */ int IMFS_evaluate_for_make( - const char *path, /* IN */ - rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ - const char **name /* OUT */ -) + const char *path, /* IN */ + rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ + const char **name /* OUT */ + ) { - int i = 0; - int len; - IMFS_token_types type; - char token[ IMFS_NAME_MAX + 1 ]; - rtems_filesystem_location_info_t newloc; - IMFS_jnode_t *node; - bool done = false; - int pathlen; - int result; + int i = 0; + int len; + IMFS_token_types type; + char token[ IMFS_NAME_MAX + 1 ]; + IMFS_jnode_t *node; + bool done = false; + size_t pathlen; + int result; /* * This was filled in by the caller and is valid in the @@ -292,7 +307,6 @@ int IMFS_evaluate_for_make( * Get the path length. */ pathlen = strlen( path ); - /* * Evaluate all tokens until we are done or an error occurs. */ @@ -313,27 +327,26 @@ int IMFS_evaluate_for_make( if ( type != IMFS_NO_MORE_PATH ) if ( node->type == IMFS_DIRECTORY ) if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_SEARCH ) ) - rtems_set_errno_and_return_minus_one( EACCES ); + rtems_set_errno_and_return_minus_one( EACCES ); node = pathloc->node_access; switch( type ) { case IMFS_UP_DIR: - /* - * Am I at the root of all filesystems? (chroot'ed?) - */ + /* + * Am I at the root of all filesystems? (chroot'ed?) + */ - if ( pathloc->node_access == rtems_filesystem_root.node_access ) - break; /* Throw out the .. in this case */ + if ( pathloc->node_access == rtems_filesystem_root.node_access ) + break; /* Throw out the .. in this case */ - /* - * Am I at the root of this mounted filesystem? - */ + /* + * Am I at the root of this mounted filesystem? + */ - if (pathloc->node_access == - pathloc->mt_entry->mt_fs_root.node_access){ + if (pathloc->node_access == pathloc->mt_entry->mt_fs_root.node_access){ /* * Am I at the root of all filesystems? @@ -341,12 +354,13 @@ int IMFS_evaluate_for_make( if ( pathloc->node_access == rtems_filesystem_root.node_access ) { break; + } else { - newloc = pathloc->mt_entry->mt_point_node; - *pathloc = newloc; - return (*pathloc->ops->evalformake_h)( &path[i], pathloc, name ); + *pathloc = pathloc->mt_entry->mt_point_node; + return (*pathloc->ops->evalformake_h)( &path[i-len], pathloc, name ); } } else { + if ( !node->Parent ) rtems_set_errno_and_return_minus_one( ENOENT ); @@ -357,9 +371,6 @@ int IMFS_evaluate_for_make( break; case IMFS_NAME: - /* - * If we are at a link follow it. - */ if ( node->type == IMFS_HARD_LINK ) { @@ -387,7 +398,7 @@ int IMFS_evaluate_for_make( rtems_set_errno_and_return_minus_one( ENOTDIR ); /* - * Otherwise find the token name in the present location. + * Find the token name in the present location. */ node = IMFS_find_match_in_dir( node, token ); @@ -400,17 +411,18 @@ int IMFS_evaluate_for_make( if ( ! node ) done = true; else { - /* - * If we are at a node that is a mount point. Set loc to the - * new fs root node and let them finish evaluating the path. - */ - - if ( node->info.directory.mt_fs != NULL ) { - newloc = node->info.directory.mt_fs->mt_fs_root; - *pathloc = newloc; - return (*pathloc->ops->evalformake_h)( &path[i], pathloc, name ); + if (( node->type == IMFS_DIRECTORY ) && ( node->info.directory.mt_fs != NULL )) { + IMFS_skip_separator( path, &pathlen, &i); + if ((path[i] != '.') || (path[i + 1] != '.')) { + *pathloc = node->info.directory.mt_fs->mt_fs_root; + return (*pathloc->ops->evalformake_h)( &path[i], + pathloc, + name ); + } + i += 2; + pathlen -= 2; + node = node->Parent; } - pathloc->node_access = node; } break; @@ -463,7 +475,6 @@ int IMFS_evaluate_for_make( return result; } - /* * IMFS_eval_path * @@ -479,13 +490,12 @@ int IMFS_eval_path( rtems_filesystem_location_info_t *pathloc /* IN/OUT */ ) { - int i = 0; - int len; - IMFS_token_types type = IMFS_CURRENT_DIR; - char token[ IMFS_NAME_MAX + 1 ]; - rtems_filesystem_location_info_t newloc; - IMFS_jnode_t *node; - int result; + int i = 0; + int len; + IMFS_token_types type = IMFS_CURRENT_DIR; + char token[ IMFS_NAME_MAX + 1 ]; + IMFS_jnode_t *node; + int result; if ( !rtems_libio_is_valid_perms( flags ) ) { rtems_set_errno_and_return_minus_one( EIO ); @@ -544,17 +554,19 @@ int IMFS_eval_path( if ( pathloc->node_access == rtems_filesystem_root.node_access ) { break; /* Throw out the .. in this case */ } else { - newloc = pathloc->mt_entry->mt_point_node; - *pathloc = newloc; - return (*pathloc->ops->evalpath_h)(&(pathname[i]), - pathnamelen, + *pathloc = pathloc->mt_entry->mt_point_node; + return (*pathloc->ops->evalpath_h)(&(pathname[i-len]), + pathnamelen+len, flags,pathloc); } } else { + if ( !node->Parent ) rtems_set_errno_and_return_minus_one( ENOENT ); node = node->Parent; + pathloc->node_access = node; + } pathloc->node_access = node; @@ -564,17 +576,17 @@ int IMFS_eval_path( /* * If we are at a link follow it. */ - if ( node->type == IMFS_HARD_LINK ) { - IMFS_evaluate_hard_link( pathloc, 0 ); - node = pathloc->node_access; - if ( !node ) - rtems_set_errno_and_return_minus_one( ENOTDIR ); + + /* + * It would be a design error if we evaluated the link and + * was broken. + */ + IMFS_assert( node ); } else if ( node->type == IMFS_SYM_LINK ) { - result = IMFS_evaluate_sym_link( pathloc, 0 ); /* @@ -589,37 +601,47 @@ int IMFS_eval_path( /* * Only a directory can be decended into. */ - if ( node->type != IMFS_DIRECTORY ) rtems_set_errno_and_return_minus_one( ENOTDIR ); /* - * Otherwise find the token name in the present location. + * Find the token name in the current node. */ - node = IMFS_find_match_in_dir( node, token ); - if ( !node ) rtems_set_errno_and_return_minus_one( ENOENT ); /* - * Set the node access to the point we have found. + * If we are at a node that is a mount point so current directory + * actually exists on the mounted file system and not in the node that + * contains the mount point node. For example a stat of the mount + * point should return the details of the root of the mounted file + * system not the mount point node of parent file system. + * + * If the node we have just moved to is a mount point do not loop and + * get the token because the token may be suitable for the mounted + * file system and not the IMFS. For example the IMFS length is + * limited. If the token is a parent directory move back up otherwise + * set loc to the new fs root node and let them finish evaluating the + * path. */ + if (( node->type == IMFS_DIRECTORY ) && ( node->info.directory.mt_fs != NULL )) { + IMFS_skip_separator( pathname, &pathnamelen, &i); + if ((pathname[i] != '.') || (pathname[i + 1] != '.')) { + *pathloc = node->info.directory.mt_fs->mt_fs_root; + return (*pathloc->ops->evalpath_h)( &pathname[i], + pathnamelen, + flags, pathloc ); + } + i += 2; + pathnamelen -= 2; + node = node->Parent; + } - pathloc->node_access = node; - /* - * If we are at a node that is a mount point. Set loc to the - * new fs root node and let them finish evaluating the path. + * Set the node access to the point we have found. */ - - if ( node->info.directory.mt_fs != NULL ) { - newloc = node->info.directory.mt_fs->mt_fs_root; - *pathloc = newloc; - return (*pathloc->ops->evalpath_h)( &pathname[i], - pathnamelen, - flags, pathloc ); - } + pathloc->node_access = node; break; case IMFS_NO_MORE_PATH: @@ -644,8 +666,7 @@ int IMFS_eval_path( if ( node->type == IMFS_DIRECTORY ) { if ( node->info.directory.mt_fs != NULL ) { - newloc = node->info.directory.mt_fs->mt_fs_root; - *pathloc = newloc; + *pathloc = node->info.directory.mt_fs->mt_fs_root; return (*pathloc->ops->evalpath_h)( &pathname[i-len], pathnamelen+len, flags, pathloc ); -- cgit v1.2.3