diff options
author | Volker Lendecke <vl@samba.org> | 2011-11-10 09:39:23 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2011-11-10 17:18:53 +0100 |
commit | 5e0258fc932c280428173bb397ef5a18352e63db (patch) | |
tree | 78327a40c73e5b9b85ef96412aba862a480cb1f0 /source3/smbd | |
parent | 17f1a97a614db4ed8292544988cb6a6cf56621d8 (diff) | |
download | samba-5e0258fc932c280428173bb397ef5a18352e63db.tar.gz samba-5e0258fc932c280428173bb397ef5a18352e63db.tar.bz2 samba-5e0258fc932c280428173bb397ef5a18352e63db.zip |
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.
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/process.c | 61 |
1 files changed, 28 insertions, 33 deletions
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)) { |