Finding: mail proxy leaves a stale upstream connection pointer after close
Summary
In freenginx, the mail proxy closes s->proxy->upstream.connection on upstream-error and session-close paths but does not clear the pointer. The closed ngx_connection_t is returned to the global free list, leaving the mail session with a non-NULL alias to a reusable connection object.
Affected Area
src/mail/ngx_mail_proxy_module.c
- Functions:
ngx_mail_proxy_upstream_error(), ngx_mail_proxy_internal_server_error(), and ngx_mail_proxy_close_session()
Source Evidence
Several paths close the upstream connection without clearing the session pointer:
if (s->proxy->upstream.connection) {
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
"close mail proxy connection: %d",
s->proxy->upstream.connection->fd);
ngx_close_connection(s->proxy->upstream.connection);
}
The same pattern appears in the upstream-error, internal-server-error, and close-session paths. After ngx_close_connection(), the connection object can be reused for another accepted or upstream connection while the mail session still has a non-NULL pointer to it.
Expected Behavior
After closing the upstream connection, the mail proxy session should clear s->proxy->upstream.connection so later logic cannot observe a stale alias to a reusable connection object.
Impact
Potential stale pointer to a reused ngx_connection_t. Follow-on reads of the non-NULL upstream connection field can observe unrelated connection state after connection reuse. This needs timing validation to demonstrate a later dereference after reuse.
Reproduction Strategy
Force upstream proxy failures while keeping the client-side mail session alive, then churn connections so the closed upstream ngx_connection_t is reused. Add an assertion or poison check that s->proxy->upstream.connection is NULL after upstream close.
Suggested Fix
Set s->proxy->upstream.connection = NULL immediately after every close of that pointer.
Finding: mail proxy leaves a stale upstream connection pointer after close
Summary
In freenginx, the mail proxy closes
s->proxy->upstream.connectionon upstream-error and session-close paths but does not clear the pointer. The closedngx_connection_tis returned to the global free list, leaving the mail session with a non-NULL alias to a reusable connection object.Affected Area
src/mail/ngx_mail_proxy_module.cngx_mail_proxy_upstream_error(),ngx_mail_proxy_internal_server_error(), andngx_mail_proxy_close_session()Source Evidence
Several paths close the upstream connection without clearing the session pointer:
The same pattern appears in the upstream-error, internal-server-error, and close-session paths. After
ngx_close_connection(), the connection object can be reused for another accepted or upstream connection while the mail session still has a non-NULL pointer to it.Expected Behavior
After closing the upstream connection, the mail proxy session should clear
s->proxy->upstream.connectionso later logic cannot observe a stale alias to a reusable connection object.Impact
Potential stale pointer to a reused
ngx_connection_t. Follow-on reads of the non-NULL upstream connection field can observe unrelated connection state after connection reuse. This needs timing validation to demonstrate a later dereference after reuse.Reproduction Strategy
Force upstream proxy failures while keeping the client-side mail session alive, then churn connections so the closed upstream
ngx_connection_tis reused. Add an assertion or poison check thats->proxy->upstream.connectionis NULL after upstream close.Suggested Fix
Set
s->proxy->upstream.connection = NULLimmediately after every close of that pointer.