You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by генерал Пурпоз <kb...@gmail.com> on 2007/02/04 00:56:30 UTC
Porting APR to QNX4: file path management.
Hello William,
Wednesday, January 31, 2007, 7:46:57 AM, you wrote:
> We presume rootpath **was** normalized previously. We presume
> addpath is untrusted user data. Now come up with a path that isn't
> insecure per the flags the developer passed.
I did my best to not ruin your code.
This is what I came up with, it passes all the tests I could think of:
--- filepath.c.orig 2006-09-21 11:43:54.000000000 +0400
+++ filepath.c 2007-02-04 02:28:26.000000000 +0300
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+#ifdef __QNX__
+#include <string.h>
+#include <sys/prfx.h>
+#endif
#include "apr.h"
#include "apr_private.h"
#include "apr_arch_file_io.h"
@@ -66,11 +70,36 @@
apr_int32_t flags,
apr_pool_t *p)
{
+ int prefix_present = 0; /* a "//number/" is in inpath */
+
if (**inpath == '/') {
+#ifdef __QNX__
+/* Are we presented with a wellformed QNX4 full path: "//number/foo" ? */
+/* A "/8/foo"-like string does NOT qualify as one. Such a string is just */
+/* an abbreviation of a "//number/8/foo"-like on-the-current-node path. */
+ if( strlen(*inpath) >= 2 && \
+ *(*inpath+1) == '/' && \
+ isdigit(*(*inpath+2)) ) prefix_present = 1;
+#else
*rootpath = apr_pstrdup(p, "/");
+#endif
do {
++(*inpath);
} while (**inpath == '/');
+#ifdef __QNX__
+ if( !prefix_present ) /* construct the rootpath anew */
+ *rootpath = apr_pstrdup(p, qnx_prefix_getroot() );
+ else { /* inpath has had a valid prefix, move in to rootpath */
+ *rootpath = apr_pstrdup(p, "//");
+ while ( isdigit(**inpath) ) {
+ strncat( *rootpath, *inpath, 1 );
+ ++(*inpath);
+ } /* move all the decimal digits representing the node ID */
+ }
+ strncat( *rootpath, "/", 1); /* now complete rootpath properly */
+ if( 0 != strlen(*inpath) && 1 == prefix_present )
+ ++(*inpath); /* deal with the post-node-number slash */
+#endif
return APR_SUCCESS;
}
@@ -91,6 +120,9 @@
apr_size_t pathlen; /* is the length of the result path */
apr_size_t seglen; /* is the end of the current segment */
apr_status_t rv;
+#ifdef __QNX__
+ int prefix_present = 0; /* a "//number/" is in addpath */
+#endif
/* Treat null as an empty path.
*/
@@ -99,7 +131,7 @@
if (addpath[0] == '/') {
/* If addpath is rooted, then rootpath is unused.
- * Ths violates any APR_FILEPATH_SECUREROOTTEST and
+ * This violates any APR_FILEPATH_SECUREROOTTEST and
* APR_FILEPATH_NOTABSOLUTE flags specified.
*/
if (flags & APR_FILEPATH_SECUREROOTTEST)
@@ -160,11 +192,41 @@
* '/'s to a single leading '/' from the addpath,
* and leave addpath at the first non-'/' character.
*/
+#ifdef __QNX__
+ keptlen = 0;
+
+/* As with apr_filepath_root() we want to know if we deal with a wellformed */
+/* QNX4-style full path: "//number/foo" ? */
+
+ if( strlen(addpath) >= 2 && \
+ addpath[1] == '/' && \
+ isdigit(addpath[2]) ) prefix_present = 1;
+ while ( addpath[0] == '/' )
+ ++addpath; /* do your usual slash-stripping at the front end */
+
+ if( !prefix_present ) {
+ strncpy( path,qnx_prefix_getroot(),strlen(qnx_prefix_getroot()) );
+ pathlen = strlen( path );
+ } else {
+ strncpy( path, "//", 2 );
+ pathlen = strlen(path);
+ while ( isdigit( addpath[0] ) ) {
+ path[pathlen] = addpath[0];
+ ++pathlen;
+ ++addpath;
+ }
+ }
+ path[pathlen] = '/';
+ ++pathlen;
+ if( 0 != strlen(addpath) && 1 == prefix_present )
+ ++addpath; /* deal with the post-node-number slash */
+#else
keptlen = 0;
while (addpath[0] == '/')
++addpath;
path[0] = '/';
pathlen = 1;
+#endif
}
else {
/* If both paths are relative, fail early
Please comment if it is a complete lunacy... :)
By the way, on my toolchain the "ABTS_STR_EQUAL(tc, "", path);"
construct needs this hacking:
"ABTS_STR_EQUAL(tc, "\0", path);"
Unless I do this the check fails no matter that the "path" string is
empty. The report complains it extected <some_string> but saw <>.
"some_string" most often is shown as "//2/". I wonder why...
--
Best regards,
Anthony mailto:kb2wjw@gmail.com