+ errno = ENOENT;
+ return ACL_ERROR;
+ }
+
+ /* Refuse to operate on hard links, which can be abused by an
+ * attacker to trick us into changing the ACL on a file we didn't
+ * intend to; namely the "target" of the hard link. To truly prevent
+ * that sort of mischief, we should be using file descriptors for
+ * the target and its parent directory. Then modulo a tiny race
+ * condition, we would be sure that "path" and "parent" don't change
+ * their nature between the time that we test them and when we
+ * utilize them. For contrast, the same attacker is free to replace
+ * "path" with a hard link after is_hardlink_safe() has returned
+ * "true" below.
+ *
+ * Unfortunately, our API is lacking in this area. For example,
+ * acl_set_fd() is only capable of setting the ACL_TYPE_ACCESS list,
+ * and not the ACL_TYPE_DEFAULT. Apparently the only way to operate
+ * on default ACLs is through the path name, which is inherently
+ * unreliable since the acl_*_file() calls themselves might follow
+ * links (both hard and symbolic).
+ *
+ * Some improvement could still be made by using descriptors where
+ * possible -- this would shrink the exploit window -- but for now
+ * we use a naive implementation that only keeps honest men honest.
+ */
+ if (!is_hardlink_safe(path)) {
+ return ACL_FAILURE;