summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2011-05-11 03:01:54 +0000
committerChris Johns <chrisj@rtems.org>2011-05-11 03:01:54 +0000
commite0ae9008ef8739c3a3ba7ffefc119d591a2d2553 (patch)
tree5ae6ac716c4b2027381072994d3075a7ddff08d3 /cpukit
parent2011-05-09 Joel Sherrill <joel.sherrill@oarcorp.com> (diff)
downloadrtems-e0ae9008ef8739c3a3ba7ffefc119d591a2d2553.tar.bz2
2011-05-11 Chris Johns <chrisj@rtems.org>
PR 1774/filesystem * libfs/src/imfs/imfs_eval.c: Updated to fix regressions found in the testsuite.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/ChangeLog8
-rw-r--r--cpukit/libfs/src/imfs/imfs_eval.c179
2 files changed, 107 insertions, 80 deletions
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 <chrisj@rtems.org>
+
+ PR 1774/filesystem
+ * libfs/src/imfs/imfs_eval.c: Updated to fix regressions found in
+ the testsuite.
+
2011-05-05 Ralf Corsépius <ralf.corsepius@rtems.org>
* librpc/include/rpc/auth.h, librpc/include/rpc/auth_unix.h,
@@ -48,7 +54,7 @@
2011-04-16 Chris Johns <chrisj@rtems.org>
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 <sebastian.huber@embedded-brains.de>
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 );