* 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:
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user