stricter handling of channel window limits
authordjm <djm@openbsd.org>
Mon, 18 Dec 2023 14:47:20 +0000 (14:47 +0000)
committerdjm <djm@openbsd.org>
Mon, 18 Dec 2023 14:47:20 +0000 (14:47 +0000)
This makes ssh/sshd more strict in handling non-compliant peers that
send more data than the advertised channel window allows. Previously
the additional data would be silently discarded. This change will
cause ssh/sshd to terminate the connection if the channel window is
exceeded by more than a small grace allowance.

ok markus@

usr.bin/ssh/channels.c
usr.bin/ssh/channels.h

index 7c611bc..0431b8c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.434 2023/11/15 22:51:49 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.435 2023/12/18 14:47:20 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -3365,11 +3365,20 @@ channel_input_data(int type, u_int32_t seq, struct ssh *ssh)
                return 0;
        }
        if (win_len > c->local_window) {
-               logit("channel %d: rcvd too much data %zu, win %u",
-                   c->self, win_len, c->local_window);
-               return 0;
+               c->local_window_exceeded += win_len - c->local_window;
+               logit("channel %d: rcvd too much data %zu, win %u/%u "
+                   "(excess %u)", c->self, win_len, c->local_window,
+                   c->local_window_max, c->local_window_exceeded);
+               c->local_window = 0;
+               /* Allow 10% grace before bringing the hammer down */
+               if (c->local_window_exceeded > (c->local_window_max / 10)) {
+                       ssh_packet_disconnect(ssh, "channel %d: peer ignored "
+                           "channel window", c->self);
+               }
+       } else {
+               c->local_window -= win_len;
+               c->local_window_exceeded = 0;
        }
-       c->local_window -= win_len;
 
        if (c->datagram) {
                if ((r = sshbuf_put_string(c->output, data, data_len)) != 0)
index b8c8883..e0893ef 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.153 2023/11/15 22:51:49 djm Exp $ */
+/* $OpenBSD: channels.h,v 1.154 2023/12/18 14:47:20 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -167,6 +167,7 @@ struct Channel {
        u_int   remote_window;
        u_int   remote_maxpacket;
        u_int   local_window;
+       u_int   local_window_exceeded;
        u_int   local_window_max;
        u_int   local_consumed;
        u_int   local_maxpacket;