Anonymous | Login | 2024-05-06 02:56 UTC |
Main | My View | View Issues | Change Log | Docs |
Viewing Issue Simple Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||
ID | Category | Severity | Type | Date Submitted | Last Update | ||
0000141 | [1003.1(2008)/Issue 7] System Interfaces | Objection | Omission | 2009-09-02 15:42 | 2013-04-16 13:06 | ||
Reporter | eblake | View Status | public | ||||
Assigned To | ajosey | ||||||
Priority | normal | Resolution | Accepted As Marked | ||||
Status | Closed | ||||||
Name | Eric Blake | ||||||
Organization | N/A | ||||||
User Reference | ebb.O_NONBLOCK | ||||||
Section | open | ||||||
Page Number | 1380 | ||||||
Line Number | 45239 | ||||||
Interp Status | Approved | ||||||
Final Accepted Text | Note: 0000232 | ||||||
Summary | 0000141: O_NONBLOCK flag to open | ||||||
Description |
The current specification of the O_NONBLOCK flag to open and openat has some holes. Older versions of the Linux kernel lacked (or silently ignored) O_DIRECTORY. Therefore, it is common to see code similar to: #ifndef O_DIRECTORY # define O_DIRECTORY 0 #endif #ifndef O_CLOEXEC # define O_CLOEXEC 0 #endif int fd = open (name, O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK | O_CLOEXEC); if (!O_DIRECTORY && 0 <= fd) { /* Prove that fd is indeed a directory. */ struct stat st; if (fstat (fd, &st) == -1 || !S_ISDIR (st.st_mode)) { close (fd); errno = ENOTDIR; fd = -1; } } The idea is that if the user can't atomically guarantee that a directory will be opened, at least they can guarantee that they won't change a controlling terminal or block on a FIFO, and can use followup checks to simulate O_DIRECTORY with minimal semantic difference. For an example of this, which goes one step further in also using O_NOFOLLOW to avoid symlink-to-directory, see http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/chdir-safer.c [^] From the POSIX perspective, the use of O_NOCTTY is safe albeit redundant - files that name directories (either a directory, or a symlink-to-directory) are mutually exclusive from terminal devices, so if name describes a directory, O_NOCTTY is silently ignored (line 45222) and open succeeds; if name is a terminal device, then O_DIRECTORY causes failure (line 45209), so the controlling terminal cannot change. And for the older non-POSIX kernels, the user has added a safety valve to prevent changing the controlling terminal until they can verify that the intent of opening a directory was met. But for O_NONBLOCK, there is a problem. For the non-POSIX case, the user has tried to add a safety valve that if name is a FIFO rather than a directory, the application will not block (avoiding a delay or even deadlock at reaching the subsequent fstat to reject the non-directory). However, according to POSIX, the use of O_NONBLOCK is unspecified on a directory, so it is conceivable that an implementation could choose to use the unspecified behavior umbrella by making open fail if name does not support non-blocking mode, rendering the combination O_DIRECTORY|O_NONBLOCK useless for a strictly compliant application (it would either fail because a non-directory was specified, or because a directory does not support non-blocking mode). Thankfully, there are no known existing implementations of open that fail if O_NONBLOCK is specified on a file that does not support non-blocking mode, although it is not clear whether a subsequent fcntl(F_GETFL) will see O_NONBLOCK. Furthermore, fcntl has no restrictions on using F_SETFL to enable O_NONBLOCK for any type of file descriptor. So, while it is currently unspecified what happens when using O_NONBLOCK to open a directory or a regular file, there appears to be no restriction on setting it later. Even if a user tries to avoid unspecified behavior associated with O_NONBLOCK by only using open(O_NONBLOCK) if they have previously stat()ed name and seen that it is a FIFO, there is an inherent data race where name can be changed to a non-FIFO between the stat() and the open(); thus it is impossible to for open(O_NONBLOCK) to ensure that it is avoiding unspecified behavior, based on the current specification. It would be nicer if the specification of O_NONBLOCK were tightened such that it is well-defined as never causing an error, similar to O_NOCTTY or O_TTY_INIT, while still leaving implementations the flexibility of ignoring the flag on file descriptors where non-blocking is not supported. That way, O_NONBLOCK can safely be used with O_DIRECTORY, and applications need not worry about triggering unspecified behavior due to a race between stat() and open(). |
||||||
Desired Action |
At line 26904 (fcntl F_GETFL), add a sentence: If filedes does not support non-blocking operations, it is unspecified whether the O_NONBLOCK flag will be ignored. At line 45239 (open O_NONBLOCK), change: Otherwise, the behavior of O_NONBLOCK is unspecified. to: Otherwise, the O_NONBLOCK flag shall not cause an error, but it is unspecified whether the file status flags will include the O_NONBLOCK flag. |
||||||
Tags | tc1-2008 | ||||||
Attached Files | |||||||
|
Relationships | ||||||
|
Issue History | |||
Date Modified | Username | Field | Change |
2009-09-02 15:42 | eblake | New Issue | |
2009-09-02 15:42 | eblake | Status | New => Under Review |
2009-09-02 15:42 | eblake | Assigned To | => ajosey |
2009-09-02 15:42 | eblake | Name | => Eric Blake |
2009-09-02 15:42 | eblake | Organization | => N/A |
2009-09-02 15:42 | eblake | User Reference | => ebb.O_NONBLOCK |
2009-09-02 15:42 | eblake | Section | => open |
2009-09-02 15:42 | eblake | Page Number | => 1380 |
2009-09-02 15:42 | eblake | Line Number | => 45239 |
2009-09-03 10:09 | geoffclare | Note Added: 0000213 | |
2009-09-03 22:37 | eblake | Note Added: 0000216 | |
2009-09-17 15:52 | nick | Note Added: 0000232 | |
2009-09-17 15:54 | nick | Interp Status | => --- |
2009-09-17 15:54 | nick | Status | Under Review => Interpretation Required |
2009-09-17 15:54 | nick | Resolution | Open => Accepted As Marked |
2009-09-17 15:55 | nick | Note Edited: 0000232 | |
2009-09-17 15:55 | nick | Final Accepted Text | => Bugnote: 232 |
2009-09-17 15:56 | nick | Interp Status | --- => Pending |
2009-09-17 15:56 | nick | Final Accepted Text | Bugnote: 232 => Note: 0000232 |
2009-09-17 15:56 | nick | Note Edited: 0000232 | |
2009-09-17 16:00 | ajosey | Note Edited: 0000232 | |
2009-11-07 07:34 | ajosey | Note Edited: 0000232 | |
2009-11-07 07:34 | ajosey | Interp Status | Pending => Proposed |
2009-12-07 16:56 | ajosey | Interp Status | Proposed => Approved |
2010-09-21 11:13 | geoffclare | Tag Attached: tc1-2008 | |
2011-11-15 01:56 | binki | Issue Monitored: binki | |
2013-02-14 16:46 | eblake | Relationship added | related to 0000658 |
2013-04-16 13:06 | ajosey | Status | Interpretation Required => Closed |
Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group |