Bug 214633 - Open symlink with O_NOFOLLOW should fail with ELOOP, not EMLINK
Summary: Open symlink with O_NOFOLLOW should fail with ELOOP, not EMLINK
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: standards (show other bugs)
Version: 11.0-RELEASE
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-standards (Nobody)
URL:
Keywords:
Depends on:
Blocks: 212572
  Show dependency treegraph
 
Reported: 2016-11-18 19:01 UTC by Ting-Wei Lan
Modified: 2016-12-04 16:01 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ting-Wei Lan 2016-11-18 19:01:06 UTC
According to POSIX standard (http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html), open function should fail to open a symlink with ELOOP when it is called with O_NOFOLLOW flag. However, it returns EMLINK on FreeBSD.

It seems it was changed by this old commit:
https://svnweb.freebsd.org/changeset/base/35088

This problem causes programs using GIO API to fail to open symlinks for writing (bug 212572).
Comment 1 Jilles Tjoelker freebsd_committer 2016-11-19 21:42:00 UTC
This question has come up before in https://lists.freebsd.org/pipermail/freebsd-fs/2011-March/010952.html. The error for O_NOFOLLOW is [EMLINK] because that allows distinguishing a symlink loop in the non-final components of the path from a symlink in the final component of the path. The implementation of cmp(1) (-h option) depends on this and contrib/xz takes advantage of it to avoid a race condition.

Perhaps an Austin group bug should be opened about this.

By the way, NetBSD returns [EFTYPE] in this case.
Comment 2 Konstantin Belousov freebsd_committer 2016-11-20 08:35:56 UTC
(In reply to Jilles Tjoelker from comment #1)
IMO the frequency of the issue raised, and the need of the appearance of the carrier of the tribal knowledge who can explain the consequences of the change, make it more reasonable to put this reasoning into the open(2) page.

Jilles, would you, please, formulate your explanation to either BUGS or STANDARDS section of the man page ?  It would be very useful for now, and even if both us and SUSvX adjust the behaviour, a historic reference is useful for very long time.
Comment 3 commit-hook freebsd_committer 2016-11-22 22:31:21 UTC
A commit references this bug:

Author: jilles
Date: Tue Nov 22 22:30:55 UTC 2016
New revision: 309026
URL: https://svnweb.freebsd.org/changeset/base/309026

Log:
  open(2): Clarify non-POSIX error when opening a symlink with O_NOFOLLOW.

  We return [EMLINK] instead of [ELOOP] when trying to open a symlink with
  O_NOFOLLOW, so that the original case of [ELOOP] can be distinguished. Code
  like cmp -h and xz takes advantage of this.

  PR:		214633
  Reviewed by:	kib, imp
  MFC after:	1 week
  Differential Revision:	https://reviews.freebsd.org/D8586

Changes:
  head/lib/libc/sys/open.2
Comment 4 Ting-Wei Lan 2016-12-04 14:39:02 UTC
I think I can close this bug now because the man page fix is already committed.
Comment 5 commit-hook freebsd_committer 2016-12-04 15:57:04 UTC
A commit references this bug:

Author: jilles
Date: Sun Dec  4 15:55:59 UTC 2016
New revision: 309533
URL: https://svnweb.freebsd.org/changeset/base/309533

Log:
  MFC r309026: open(2): Clarify non-POSIX error when opening a symlink with
  O_NOFOLLOW.

  We return [EMLINK] instead of [ELOOP] when trying to open a symlink with
  O_NOFOLLOW, so that the original case of [ELOOP] can be distinguished. Code
  like cmp -h and xz takes advantage of this.

  PR:		214633

Changes:
  stable/11/lib/libc/sys/open.2
Comment 6 commit-hook freebsd_committer 2016-12-04 16:01:09 UTC
A commit references this bug:

Author: jilles
Date: Sun Dec  4 16:00:25 UTC 2016
New revision: 309536
URL: https://svnweb.freebsd.org/changeset/base/309536

Log:
  MFC r309026: open(2): Clarify non-POSIX error when opening a symlink with
  O_NOFOLLOW.

  We return [EMLINK] instead of [ELOOP] when trying to open a symlink with
  O_NOFOLLOW, so that the original case of [ELOOP] can be distinguished. Code
  like cmp -h and xz takes advantage of this.

  PR:		214633

Changes:
_U  stable/10/
  stable/10/lib/libc/sys/open.2