aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-06-12 17:45:42 +0000
committerCorinna Vinschen <corinna@vinschen.de>2013-06-12 17:45:42 +0000
commit0b8722c2dba53724769ddfcf2fa39baf0ae253a7 (patch)
tree3f3b581fbc3cdc33c11a31cac9d419738353aabf
parentbb345ed1471114fe5b9b1a1fd561b3b6f4b1d645 (diff)
downloadnewlib-0b8722c2dba53724769ddfcf2fa39baf0ae253a7.zip
newlib-0b8722c2dba53724769ddfcf2fa39baf0ae253a7.tar.gz
newlib-0b8722c2dba53724769ddfcf2fa39baf0ae253a7.tar.bz2
* path.cc (normalize_posix_path): Fix long-standing problem which
allows to access files via ".." using an invalid POSIX path.
-rw-r--r--winsup/cygwin/ChangeLog5
-rw-r--r--winsup/cygwin/path.cc17
-rw-r--r--winsup/cygwin/release/1.7.2110
3 files changed, 32 insertions, 0 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 158369b..15e9496 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,8 @@
+2013-06-12 Fedin Pavel <p.fedin@samsung.com>
+
+ * path.cc (normalize_posix_path): Fix long-standing problem which
+ allows to access files via ".." using an invalid POSIX path.
+
2013-06-11 Corinna Vinschen <corinna@vinschen.de>
* winver.rc (FileDescription): Remove (R).
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 16571b1..e0fa376 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -240,6 +240,7 @@ normalize_posix_path (const char *src, char *dst, char *&tail)
{
const char *in_src = src;
char *dst_start = dst;
+ bool check_parent = false;
syscall_printf ("src %s", src);
if ((isdrive (src) && isdirsep (src[2])) || *src == '\\')
@@ -278,6 +279,7 @@ normalize_posix_path (const char *src, char *dst, char *&tail)
*tail++ = *src++;
else
{
+ check_parent = true;
while (*++src)
{
if (isslash (*src))
@@ -301,6 +303,21 @@ normalize_posix_path (const char *src, char *dst, char *&tail)
break;
else
{
+ /* According to POSIX semantics all elements of path must
+ exist. To follow it, we must validate our path before
+ removing the trailing component. Check_parent is needed
+ for performance optimization, in order not to verify paths
+ which are already verified. For example this prevents
+ double check in case of foo/bar/../.. */
+ if (check_parent)
+ {
+ *tail = 0;
+ debug_printf ("checking %s before '..'", dst_start);
+ path_conv head (dst_start);
+ if (!head.isdir())
+ return ENOENT;
+ check_parent = false;
+ }
while (tail > dst_start && !isslash (*--tail))
continue;
src++;
diff --git a/winsup/cygwin/release/1.7.21 b/winsup/cygwin/release/1.7.21
new file mode 100644
index 0000000..0eb3de3
--- /dev/null
+++ b/winsup/cygwin/release/1.7.21
@@ -0,0 +1,10 @@
+What's new:
+-----------
+
+
+Bug fixes:
+----------
+
+- Fix long-standing problem which allows to access files via ".." using an
+ invalid POSIX path, for instance, `cd nonexistant/../existing_dir".
+ Fixes: http://cygwin.com/ml/cygwin/2013-05/msg00222.html