https://bz.apache.org/bugzilla/show_bug.cgi?id=70106
Bug ID: 70106
Summary: Use-After-Close in ap_duplicate_listeners due to
unhandled make_sock return value
Product: Apache httpd-2
Version: 2.5-HEAD
Hardware: PC
OS: Mac OS X 10.1
Status: NEW
Severity: normal
Priority: P2
Component: Core
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
**Summary:** During server startup or graceful restart, the
`ap_duplicate_listeners` function creates a new socket descriptor and
configures it via `make_sock`. However, the return value of `make_sock` is not
checked. If `make_sock` encounters an error and closes the socket internally,
`ap_duplicate_listeners` will continue execution and subsequently attempt to
apply socket options to the already-closed file descriptor, leading to a
Use-After-Close (UAC) condition.
**Bug Detail:** The vulnerability lies in the interaction between
`ap_duplicate_listeners` and `make_sock` in `server/listen.c`.
1. At **line 904** in `ap_duplicate_listeners`, a new socket is created: `stat
= apr_socket_create(&duplr->sd, ...);`
2. At **line 913**, the socket is passed to `make_sock` for configuration:
`make_sock(p, duplr, 1);` // <-- Return value is ignored
3. Inside `make_sock` (starting at **line 72**), a local pointer alias to the
socket descriptor is established at **line 74**:
```C
apr_socket_t *s = server->sd;
```
If any subsequent `apr_socket_opt_set` call fails (e.g., `APR_SO_REUSEADDR`
or `APR_SO_KEEPALIVE`), the function handles the error by logging it, closing
the socket `s` (which aliases `duplr->sd`), and returning an error code. For
example, around **lines 87-92**:
```C
if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
ap_log_perror(...);
apr_socket_close(s); // Socket is closed here (First Free)
return stat;
}
```
4. Back in `ap_duplicate_listeners`, because the return value of `make_sock` is
ignored, the execution continues. At **line 917** (inside the
`AP_NONBLOCK_WHEN_MULTI_LISTEN` block), the code attempts to apply a socket
option to the original reference:
```C
stat = apr_socket_opt_set(duplr->sd, APR_SO_NONBLOCK, use_nonblock); // UAC
triggered here
```
At this point, `duplr->sd` holds a closed descriptor, triggering undefined
behavior or a crash depending on the underlying APR implementation.
**Impact:** This is a reliability and stability defect. If the local system
encounters an environment issue or resource exhaustion that causes `make_sock`
to fail during server initialization or a graceful restart, the httpd parent
process will likely crash due to operating on a closed descriptor, rather than
exiting gracefully with an appropriate fatal error message.
*(Note for triage: This has been evaluated against the Apache httpd security
model. Because this path is restricted to the startup/restart phase and cannot
be triggered by remote untrusted clients, it does not represent a remote attack
vector. It is reported here as a core stability bug.)*
**Fix:** The return value of `make_sock` must be checked. If it fails,
`ap_duplicate_listeners` should propagate the error upward immediately to
prevent further operations on the closed descriptor.
```Diff
--- server/listen.c
+++ server/listen.c
@@ -910,7 +910,10 @@
duplr->bind_addr);
return stat;
}
- make_sock(p, duplr, 1);
+ stat = make_sock(p, duplr, 1);
+ if (stat != APR_SUCCESS) {
+ return stat;
+ }
}
#if AP_NONBLOCK_WHEN_MULTI_LISTEN
use_nonblock = (ap_listeners && ap_listeners->next);
```
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]