s3: Fix the async echo responder for netbios keepalives
authorVolker Lendecke <vl@samba.org>
Wed, 6 Oct 2010 16:24:13 +0000 (18:24 +0200)
committerVolker Lendecke <vl@samba.org>
Thu, 7 Oct 2010 09:47:45 +0000 (11:47 +0200)
This fixes a crash in the echo responder when the client started to send the
NetBIOS-Level 0x85-style keepalive packets. We did not correctly check the
packet length, so the code writing the signing seqnum overwrote memory after
the malloc'ed area for the 4 byte keepalive packet.

source3/smbd/process.c

index 36f31dfed692210abfdcf9ac472963ab061ca817..cf50417cff2428d4edd5e449dbb9aa67730d5f81 100644 (file)
@@ -2267,6 +2267,14 @@ static bool smbd_echo_reply(int fd,
        char *outbuf;
        bool ok;
 
+       if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
+               DEBUG(10, ("Got netbios keepalive\n"));
+               /*
+                * Just swallow it
+                */
+               return true;
+       }
+
        if (inbuf_len < smb_size) {
                DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
                return false;
@@ -2400,13 +2408,6 @@ static void smbd_echo_reader(struct tevent_context *ev,
                exit(1);
        }
 
-       /*
-        * place the seqnum in the packet so that the main process can reply
-        * with signing
-        */
-       SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
-       SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
-
        reply = smbd_echo_reply(smbd_server_fd(),
                                (uint8_t *)state->pending[num_pending].iov_base,
                                state->pending[num_pending].iov_len,
@@ -2417,10 +2418,22 @@ static void smbd_echo_reader(struct tevent_context *ev,
                state->pending = talloc_realloc(state, state->pending,
                                                struct iovec,
                                                num_pending);
-       } else {
-               DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
-               smbd_echo_activate_writer(state);
+               return;
+       }
+
+       if (state->pending[num_pending].iov_len >= smb_size) {
+               /*
+                * place the seqnum in the packet so that the main process
+                * can reply with signing
+                */
+               SIVAL((uint8_t *)state->pending[num_pending].iov_base,
+                     smb_ss_field, seqnum);
+               SIVAL((uint8_t *)state->pending[num_pending].iov_base,
+                     smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
        }
+
+       DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
+       smbd_echo_activate_writer(state);
 }
 
 static void smbd_echo_loop(struct smbd_server_connection *sconn,