From 5e0258fc932c280428173bb397ef5a18352e63db Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 10 Nov 2011 09:39:23 +0100 Subject: s3: Avoid a race with the async echo handler We can not read from the echo handler socket when we have the main socket locked. This leads to the echo responder to lock up sitting in the fcntl lock while the parent wants to read the remainder of a large packet. --- source3/smbd/process.c | 61 +++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 33 deletions(-) (limited to 'source3/smbd/process.c') diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 0ad554228b..82dd51048e 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -2217,46 +2217,41 @@ static void smbd_server_connection_read_handler( NTSTATUS status; uint32_t seqnum; - bool from_client = (sconn->sock == fd); + bool from_client; + + if (lp_async_smb_echo_handler() + && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) { + /* + * This is the super-ugly hack to prefer the packets + * forwarded by the echo handler over the ones by the + * client directly + */ + fd = sconn->smb1.echo_handler.trusted_fd; + } + + from_client = (sconn->sock == fd); if (from_client) { smbd_lock_socket(sconn); - if (lp_async_smb_echo_handler()) { - - if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) { - /* - * This is the super-ugly hack to - * prefer the packets forwarded by the - * echo handler over the ones by the - * client directly - */ - fd = sconn->smb1.echo_handler.trusted_fd; - } else if (!fd_is_readable(fd)) { - DEBUG(10,("the echo listener was faster\n")); - smbd_unlock_socket(sconn); - return; - } + if (!fd_is_readable(fd)) { + DEBUG(10,("the echo listener was faster\n")); + smbd_unlock_socket(sconn); + return; } + } + + /* TODO: make this completely nonblocking */ + status = receive_smb_talloc(mem_ctx, sconn, fd, + (char **)(void *)&inbuf, + 0, /* timeout */ + &unread_bytes, + &encrypted, + &inbuf_len, &seqnum, + false /* trusted channel */); - /* TODO: make this completely nonblocking */ - status = receive_smb_talloc(mem_ctx, sconn, fd, - (char **)(void *)&inbuf, - 0, /* timeout */ - &unread_bytes, - &encrypted, - &inbuf_len, &seqnum, - false /* trusted channel */); + if (from_client) { smbd_unlock_socket(sconn); - } else { - /* TODO: make this completely nonblocking */ - status = receive_smb_talloc(mem_ctx, sconn, fd, - (char **)(void *)&inbuf, - 0, /* timeout */ - &unread_bytes, - &encrypted, - &inbuf_len, &seqnum, - true /* trusted channel */); } if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) { -- cgit