+
+ fd = safe_open(path, O_NOFOLLOW);
+ if (fd == OPEN_ERROR) {
+ if (errno == ELOOP) {
+ result = ACL_FAILURE; /* hit a symlink */
+ goto cleanup;
+ }
+ else {
+ perror("apply_default_acl (open fd)");
+ result = ACL_ERROR;
+ goto cleanup;
+ }
+ }
+
+
+ /* 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. There is TOCTOU
+ * race condition here, but the window is as small as possible
+ * between when we open the file descriptor (look above) and when we
+ * fstat it.
+ *
+ * Note: we only need to call fstat ourselves if we weren't passed a
+ * valid pointer to a stat structure (nftw does that).
+ */
+ if (sp == NULL) {
+ struct stat s;
+ if (fstat(fd, &s) == STAT_ERROR) {
+ perror("apply_default_acl (fstat)");
+ goto cleanup;
+ }
+
+ sp = &s;
+ }
+
+ if (!S_ISDIR(sp->st_mode)) {
+ /* If it's not a directory, make sure it's a regular,
+ non-hard-linked file. */
+ if (!S_ISREG(sp->st_mode) || sp->st_nlink != 1) {
+ result = ACL_FAILURE;
+ goto cleanup;
+ }