diff options
author | bojan <bojan@13f79535-47bb-0310-9956-ffa450edef68> | 2009-11-01 06:07:57 +0000 |
---|---|---|
committer | bojan <bojan@13f79535-47bb-0310-9956-ffa450edef68> | 2009-11-01 06:07:57 +0000 |
commit | 83cf27829e34c8a43be515076d3103f55007096e (patch) | |
tree | 3543131d19c31b14f4917d8e5462e531aad6869e | |
parent | eb0c2ecfde798134697b1ad23ef94a83a75fd3e7 (diff) | |
download | libapr-83cf27829e34c8a43be515076d3103f55007096e.tar.gz |
Backport r831641 from the trunk.
Set file/socket descriptor to -1 before close(), so that there is no chance
of returning an already closed FD from apr_os_file_get()/apr_os_sock_get().
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/branches/1.4.x@831642 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | file_io/unix/open.c | 11 | ||||
-rw-r--r-- | network_io/unix/sockets.c | 12 |
2 files changed, 19 insertions, 4 deletions
diff --git a/file_io/unix/open.c b/file_io/unix/open.c index e10fc3dda..bf3b43b6a 100644 --- a/file_io/unix/open.c +++ b/file_io/unix/open.c @@ -29,10 +29,14 @@ static apr_status_t file_cleanup(apr_file_t *file, int is_child) { apr_status_t rv = APR_SUCCESS; + int fd = file->filedes; - if (close(file->filedes) == 0) { - file->filedes = -1; + /* Set file descriptor to -1 before close(), so that there is no + * chance of returning an already closed FD from apr_os_file_get(). + */ + file->filedes = -1; + if (close(fd) == 0) { /* Only the parent process should delete the file! */ if (!is_child && (file->flags & APR_DELONCLOSE)) { unlink(file->fname); @@ -44,6 +48,9 @@ static apr_status_t file_cleanup(apr_file_t *file, int is_child) #endif } else { + /* Restore, close() was not successful. */ + file->filedes = fd; + /* Are there any error conditions other than EINTR or EBADF? */ rv = errno; } diff --git a/network_io/unix/sockets.c b/network_io/unix/sockets.c index a379b7bdd..5552460ed 100644 --- a/network_io/unix/sockets.c +++ b/network_io/unix/sockets.c @@ -31,12 +31,20 @@ static char generic_inaddr_any[16] = {0}; /* big enough for IPv4 or IPv6 */ static apr_status_t socket_cleanup(void *sock) { apr_socket_t *thesocket = sock; + int sd = thesocket->socketdes; - if (close(thesocket->socketdes) == 0) { - thesocket->socketdes = -1; + /* Set socket descriptor to -1 before close(), so that there is no + * chance of returning an already closed FD from apr_os_sock_get(). + */ + thesocket->socketdes = -1; + + if (close(sd) == 0) { return APR_SUCCESS; } else { + /* Restore, close() was not successful. */ + thesocket->socketdes = sd; + return errno; } } |