summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbojan <bojan@13f79535-47bb-0310-9956-ffa450edef68>2009-11-01 06:07:57 +0000
committerbojan <bojan@13f79535-47bb-0310-9956-ffa450edef68>2009-11-01 06:07:57 +0000
commit83cf27829e34c8a43be515076d3103f55007096e (patch)
tree3543131d19c31b14f4917d8e5462e531aad6869e
parenteb0c2ecfde798134697b1ad23ef94a83a75fd3e7 (diff)
downloadlibapr-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.c11
-rw-r--r--network_io/unix/sockets.c12
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;
}
}