* 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.
This commit is contained in:
Corinna Vinschen
2014-04-18 14:29:49 +00:00
parent d98d7f3973
commit 7ae3e6b3d4
8 changed files with 282 additions and 233 deletions

View File

@@ -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;
}