aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorKen Brown <kbrown@cornell.edu>2020-09-28 16:34:44 -0400
committerKen Brown <kbrown@cornell.edu>2020-10-04 12:53:05 -0400
commit0b4beaf46f34869aa2773c08a658e8aadba496e1 (patch)
treed35eb247e122ec1c3406900cddda77ce6562a021 /winsup
parent4b4fffe0f2390be6a5be27b6a3ceaa212a3724b2 (diff)
downloadnewlib-0b4beaf46f34869aa2773c08a658e8aadba496e1.zip
newlib-0b4beaf46f34869aa2773c08a658e8aadba496e1.tar.gz
newlib-0b4beaf46f34869aa2773c08a658e8aadba496e1.tar.bz2
Cygwin: fix handling of known reparse points that are not symlinks
Commit aa467e6e, "Cygwin: add AF_UNIX reparse points to path handling", changed check_reparse_point_target so that it could return a positive value on a known reparse point that is not a symlink. But some of the code in check_reparse_point that handles this positive return value was executed unconditionally, when it should have been executed only for symlinks. As a result, posixify could be called on a buffer containing garbage, and check_reparse_point could erroneously return a positive value on a non-symlink. This is now fixed so that posixify is only called if the reparse point is a symlink, and check_reparse_point returns 0 if the reparse point is not a symlink. Also fix symlink_info::check to handle this last case, in which check_reparse_point returns 0 on a known reparse point.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/path.cc17
1 files changed, 12 insertions, 5 deletions
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 638f1ad..2e3208d 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -2655,11 +2655,15 @@ symlink_info::check_reparse_point (HANDLE h, bool remote)
/* ret is > 0, so it's a known reparse point, path in symbuf. */
path_flags |= ret;
if (ret & PATH_SYMLINK)
- sys_wcstombs (srcbuf, SYMLINK_MAX + 7, symbuf.Buffer,
- symbuf.Length / sizeof (WCHAR));
- /* A symlink is never a directory. */
- fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
- return posixify (srcbuf);
+ {
+ sys_wcstombs (srcbuf, SYMLINK_MAX + 7, symbuf.Buffer,
+ symbuf.Length / sizeof (WCHAR));
+ /* A symlink is never a directory. */
+ fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
+ return posixify (srcbuf);
+ }
+ else
+ return 0;
}
int
@@ -3274,6 +3278,9 @@ restart:
&= ~FILE_ATTRIBUTE_DIRECTORY;
break;
}
+ else if (res == 0 && (path_flags & PATH_REP))
+ /* Known reparse point but not a symlink. */
+ goto file_not_symlink;
else
{
/* Volume moint point or unrecognized reparse point type.