From 0b8722c2dba53724769ddfcf2fa39baf0ae253a7 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 12 Jun 2013 17:45:42 +0000 Subject: [PATCH] * path.cc (normalize_posix_path): Fix long-standing problem which allows to access files via ".." using an invalid POSIX path. --- winsup/cygwin/ChangeLog | 5 +++++ winsup/cygwin/path.cc | 17 +++++++++++++++++ winsup/cygwin/release/1.7.21 | 10 ++++++++++ 3 files changed, 32 insertions(+) create mode 100644 winsup/cygwin/release/1.7.21 diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 158369bee..15e949624 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,8 @@ +2013-06-12 Fedin Pavel + + * 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 * winver.rc (FileDescription): Remove (R). diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 16571b12e..e0fa37670 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 000000000..0eb3de3a4 --- /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