From e176ee0b5d8e90b0d3871ee778d290bc3d6abe96 Mon Sep 17 00:00:00 2001
From: =?utf8?q?P=C3=A1draig=20Brady?=
Date: Thu, 28 May 2015 14:15:08 +0100
Subject: [PATCH] unlinkat: handle ignoring of ".." on Darwin 14
* lib/unlinkat.c: unlinkat() has the same bug as unlink()
on Mac OS X 10.10, where it ignores paths with a trailing "..",
so handle in the same manner.
* m4/unlinkat.m4: Comment on this Darwin issue.
* doc/posix-functions/unlink.texi: Update the latest version
where the issue was seen.
* doc/posix-functions/unlinkat.texi: Mention this issue.
Fixes a test failure in test-unlinkat.c.
---
ChangeLog | 12 ++++++++++++
doc/posix-functions/unlink.texi | 2 +-
doc/posix-functions/unlinkat.texi | 3 +++
lib/unlinkat.c | 21 +++++++++++++++++----
m4/unlinkat.m4 | 1 +
5 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 517d439c68..035fb7aefd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2015-05-28 Pádraig Brady
+
+ unlinkat: handle ignoring of ".." on Darwin 14
+ * lib/unlinkat.c: unlinkat() has the same bug as unlink()
+ on Mac OS X 10.10, where it ignores paths with a trailing "..",
+ so handle in the same manner.
+ * m4/unlinkat.m4: Comment on this Darwin issue.
+ * doc/posix-functions/unlink.texi: Update the latest version
+ where the issue was seen.
+ * doc/posix-functions/unlinkat.texi: Mention this issue.
+ Fixes a test failure in test-unlinkat.c.
+
2015-05-27 Paul Eggert
qacl: split into qcopy-acl and qset-acl
diff --git a/doc/posix-functions/unlink.texi b/doc/posix-functions/unlink.texi
index 53520a10c1..171e9facd6 100644
--- a/doc/posix-functions/unlink.texi
+++ b/doc/posix-functions/unlink.texi
@@ -12,7 +12,7 @@ Portability problems fixed by Gnulib:
Some systems mistakenly succeed on @code{unlink("link-to-file/")}:
GNU/Hurd, FreeBSD 7.2, AIX 7.1, Solaris 9.
@item
-On Mac OS X 10.5.6, in a writable HFS mount, @code{unlink("..")} succeeds
+On Mac OS X 10.10, in a writable HFS mount, @code{unlink("..")} succeeds
without doing anything.
@end itemize
diff --git a/doc/posix-functions/unlinkat.texi b/doc/posix-functions/unlinkat.texi
index fe751b7ab4..bfa20e6fd3 100644
--- a/doc/posix-functions/unlinkat.texi
+++ b/doc/posix-functions/unlinkat.texi
@@ -14,6 +14,9 @@ glibc 2.3.6, Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8,
AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Cygwin 1.5.x, mingw, MSVC 9, Interix 3.5, BeOS.
But the replacement function is not safe to be used in libraries and is not multithread-safe.
@item
+On Mac OS X 10.10, in a writable HFS mount, @code{unlinkat(fd, "..", 0)} succeeds
+without doing anything.
+@item
Some systems mistakenly succeed on @code{unlinkat(fd,"file/",flag)}:
GNU/Hurd, Solaris 9.
@item
diff --git a/lib/unlinkat.c b/lib/unlinkat.c
index 0d89bf9744..af35256fd0 100644
--- a/lib/unlinkat.c
+++ b/lib/unlinkat.c
@@ -35,9 +35,12 @@
# undef unlinkat
-/* unlinkat without AT_REMOVEDIR does not honor trailing / on Solaris
- 9. Solve it in a similar manner to unlink. Hurd has the same
- issue. */
+/* unlinkat without AT_REMOVEDIR does not honor trailing / on Solaris 9.
+ Hurd has the same issue.
+
+ unlinkat without AT_REMOVEDIR erroneously ignores ".." on Darwin 14.
+
+ Solve these in a similar manner to unlink. */
int
rpl_unlinkat (int fd, char const *name, int flag)
@@ -78,7 +81,17 @@ rpl_unlinkat (int fd, char const *name, int flag)
}
}
if (!result)
- result = unlinkat (fd, name, flag);
+ {
+# if UNLINK_PARENT_BUG
+ if (len >= 2 && name[len - 1] == '.' && name[len - 2] == '.'
+ && (len == 2 || ISSLASH (name[len - 3])))
+ {
+ errno = EISDIR; /* could also use EPERM */
+ return -1;
+ }
+# endif
+ result = unlinkat (fd, name, flag);
+ }
return result;
}
diff --git a/m4/unlinkat.m4 b/m4/unlinkat.m4
index 6e5fa31802..be70c4fefc 100644
--- a/m4/unlinkat.m4
+++ b/m4/unlinkat.m4
@@ -24,6 +24,7 @@ AC_DEFUN([gl_FUNC_UNLINKAT],
;;
*)
# GNU/Hurd has unlinkat, but it has the same bug as unlink.
+ # Darwin has unlinkat, but it has the same UNLINK_PARENT_BUG.
if test $REPLACE_UNLINK = 1; then
REPLACE_UNLINKAT=1
fi
--
2.39.5