mirror of
https://github.com/samba-team/samba.git
synced 2025-01-21 18:04:06 +03:00
smbd: Remove callback for release_ip when "state" is free'ed
If a client connects to a non-public address first followed by a connect to public address with the same client_guid and a connection to the non-public address gets disconnected first, we hit by a use-after-free talloc_get_type_abort() called from release_ip() as "xconn" is already gone, taking smbd_release_ip_state with it. We need to decide between calling ctdbd_unregister_ips() by default, as it means the tcp connection is really gone and ctdb needs to remove the 'tickle' information. But when a connection was passed to a different smbd process, we need to use ctdbd_passed_ips() as the tcp connection is still alive and the 'tickle' information should not be removed within ctdb. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523 Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> Signed-off-by: Volker Lendecke <vl@samba.org> Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Martin Schwenke <martin@meltin.net> (cherry picked from commit ddf47e7fe314e0f5bf71ff53e35350e0ba530d08)
This commit is contained in:
parent
f8c02609f4
commit
279187965b
@ -1,4 +0,0 @@
|
||||
^samba3.blackbox.smbXsrv_client_ctdb_registered_ips.step5:.ctdb_gettickles.NUM
|
||||
^samba3.blackbox.smbXsrv_client_ctdb_registered_ips.step5:.ctdb_gettickles.DST
|
||||
^samba3.blackbox.smbXsrv_client_ctdb_registered_ips.step6:.ctdb_gettickles.NUM
|
||||
^samba3.blackbox.smbXsrv_client_ctdb_registered_ips.step6:.ctdb_gettickles.DST
|
@ -1 +0,0 @@
|
||||
^samba3.blackbox.smbXsrv_client_ctdb_registered_ips.step7:.smbstatus.0.sessions
|
@ -877,7 +877,14 @@ static void smbd_smb2_request_process_negprot_mc_done(struct tevent_req *subreq)
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_MESSAGE_RETRIEVED)) {
|
||||
/*
|
||||
* The connection was passed to another process
|
||||
*
|
||||
* We mark the error as NT_STATUS_CONNECTION_IN_USE,
|
||||
* in order to indicate to low level code if
|
||||
* ctdbd_unregister_ips() or ctdbd_passed_ips()
|
||||
* is more useful.
|
||||
*/
|
||||
smbXsrv_connection_disconnect_transport(xconn,
|
||||
NT_STATUS_CONNECTION_IN_USE);
|
||||
smbd_server_connection_terminate(xconn,
|
||||
"passed connection");
|
||||
/*
|
||||
|
@ -1017,9 +1017,37 @@ static void smbd_server_connection_handler(struct tevent_context *ev,
|
||||
struct smbd_release_ip_state {
|
||||
struct smbXsrv_connection *xconn;
|
||||
struct tevent_immediate *im;
|
||||
struct sockaddr_storage srv;
|
||||
struct sockaddr_storage clnt;
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
};
|
||||
|
||||
static int release_ip(struct tevent_context *ev,
|
||||
uint32_t src_vnn,
|
||||
uint32_t dst_vnn,
|
||||
uint64_t dst_srvid,
|
||||
const uint8_t *msg,
|
||||
size_t msglen,
|
||||
void *private_data);
|
||||
|
||||
static int smbd_release_ip_state_destructor(struct smbd_release_ip_state *s)
|
||||
{
|
||||
struct ctdbd_connection *cconn = messaging_ctdb_connection();
|
||||
struct smbXsrv_connection *xconn = s->xconn;
|
||||
|
||||
if (cconn == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_CONNECTION_IN_USE)) {
|
||||
ctdbd_passed_ips(cconn, &s->srv, &s->clnt, release_ip, s);
|
||||
} else {
|
||||
ctdbd_unregister_ips(cconn, &s->srv, &s->clnt, release_ip, s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void smbd_release_ip_immediate(struct tevent_context *ctx,
|
||||
struct tevent_immediate *im,
|
||||
void *private_data)
|
||||
@ -1162,6 +1190,8 @@ static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
|
||||
if (state->im == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
state->srv = *srv;
|
||||
state->clnt = *clnt;
|
||||
if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
@ -1185,6 +1215,9 @@ static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
|
||||
if (ret != 0) {
|
||||
return map_nt_error_from_unix(ret);
|
||||
}
|
||||
|
||||
talloc_set_destructor(state, smbd_release_ip_state_destructor);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user