diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2014-04-18 14:29:49 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2014-04-18 14:29:49 +0000 |
commit | 7ae3e6b3d47492b938966b923c4065b76cf8762a (patch) | |
tree | 36cd1c4b49e440ee70369e0d002eaec3c2fcd0d9 /winsup/cygwin/path.cc | |
parent | d98d7f397389cca8f96318a1644431012a6211be (diff) | |
download | cygnal-7ae3e6b3d47492b938966b923c4065b76cf8762a.tar.gz cygnal-7ae3e6b3d47492b938966b923c4065b76cf8762a.tar.bz2 cygnal-7ae3e6b3d47492b938966b923c4065b76cf8762a.zip |
* cygtls.h (TP_NUM_C_BUFS): Raise to 50 to allow SYMLOOP_MAX recursions
path_conv <-> normalize_posix_path, plus a bit of buffer.
(TP_NUM_W_BUFS): Ditto.
(class san): Change type of _c_cnt and _w_cnt to unsigned.
* path.cc (normalize_posix_path): Guard recursion into path_conv
against tmp_pathbuf overflow. Generate normalized path in call to
path_conv. If the path is valid, replace dst with the normalized_path
from path_conv call. Add comment to explain why we're doing this.
* tls_pbuf.cc (tls_pathbuf::destroy): Only free buffers until the
first buffer pointer is NULL.
(tmp_pathbuf::c_get): Simplify error message.
(tmp_pathbuf::w_get): Ditto.
* tls_pbuf.h (class tmp_pathbuf): Change type of c_buf_old and w_buf_old
to unsigned.
(tmp_pathbuf::check_usage): New inline method to check if we have
enough tmp_pathbuf buffers left to call a function using tmp_pathbuf
buffers.
* tlsoffsets.h: Regenerate.
* tlsoffsets64.h: Regenerate.
Diffstat (limited to 'winsup/cygwin/path.cc')
-rw-r--r-- | winsup/cygwin/path.cc | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 4990328a2..631b169a0 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -311,9 +311,31 @@ normalize_posix_path (const char *src, char *dst, char *&tail) { *tail = 0; debug_printf ("checking %s before '..'", dst); - path_conv head (dst); + /* In conjunction with native and NFS symlinks, + this call can result in a recursion which eats + up our tmp_pathbuf buffers. This in turn results + in a api_fatal call. To avoid that, we're + checking our remaining buffers and return an + error code instead. Note that this only happens + if the path contains 15 or more relative native/NFS + symlinks with a ".." in the target path. */ + tmp_pathbuf tp; + if (!tp.check_usage (4, 3)) + return ELOOP; + path_conv head (dst, PC_SYM_FOLLOW | PC_POSIX); if (!head.isdir()) return ENOENT; + /* At this point, dst is a normalized path. If the + normalized path created by path_conv does not + match the normalized path we're just testing, then + the path in dst contains native symlinks. If we + just plunge along, removing the previous path + component, we may end up removing a symlink from + the path and the resulting path will be invalid. + So we replace dst with what we found in head + instead. All the work replacing symlinks has been + done in that path anyway, so why repeat it? */ + tail = stpcpy (dst, head.normalized_path); } check_parent = false; } |