Summary: | freopen does not check dup3 return value, and does not return error if dup3 fails (seen when open returns fd 0, and freopen on stdin) | ||
---|---|---|---|
Product: | glibc | Reporter: | Dave Olson <olson> |
Component: | stdio | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED DUPLICATE | ||
Severity: | normal | CC: | fweimer |
Priority: | P2 | Flags: | fweimer:
security-
|
Version: | 2.25 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Last reconfirmed: |
Description
Dave Olson
2017-04-18 23:12:24 UTC
I don't think using a stream where the underlying file descriptor is closed has defined behviour. (In reply to Andreas Schwab from comment #1) > I don't think using a stream where the underlying file descriptor is closed > has defined behviour. This conflicts with previous guidance I got. Applications are supposed to be able to close descriptors used by the library (which is why we can't keep open a descriptor for /dev/urandom, for example). Given this, it appears to be reasonable to expect that it is possible to resurrect a stream using freopen if its underlying descriptor has been closed. In the (non-normative) application usage of close POSIX says: "Usage of close() on file descriptors STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO should immediately be followed by an operation to reopen these file descriptors." (In reply to Andreas Schwab from comment #3) > In the (non-normative) application usage of close POSIX says: "Usage of > close() on file descriptors STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO > should immediately be followed by an operation to reopen these file > descriptors." But this doesn't say whether you can use freopen for that purpose. freopen operates on streams, not file descriptors. It's not trying to use a stream where the underlying fd is closed, it's trying to create stdin. Think of processes that are exec'ed without fd 0 open (which is the real test case, because it's marked close on exec). What it's trying to do is to establish a stdin for use with functions that expect to use stdin. Even if you don't accept that as a valid use case (and I can accept the argument, even though I don't agree with it), freopen() should be returning an error, which means it needs to check for dup3 returning errors. Right now, freopen in this situation returns what appears to be a valid FILE *, but the requested action on stdin will fail. So the minimum is to check for dup3() errors, and then return an error from freopen(). |