aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2023-12-18 14:47:20 +0000
committerDamien Miller <djm@mindrot.org>2023-12-19 01:52:55 +1100
commit0cb50eefdd29f0fec31d0e71cc4b004a5f704e67 (patch)
tree8bca2581bdf5d716cd55395c079167e9b708d58d
parent4448a2938abc76e6bd33ba09b2ec17a216dfb491 (diff)
downloadopenssh-0cb50eefdd29f0fec31d0e71cc4b004a5f704e67.tar.gz
upstream: stricter handling of channel window limits
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@ OpenBSD-Commit-ID: 811e21b41831eba3dd7f67b3d409a438f20d3037
-rw-r--r--channels.c19
-rw-r--r--channels.h3
2 files changed, 16 insertions, 6 deletions
diff --git a/channels.c b/channels.c
index 38135e5ad..20f31dadd 100644
--- a/channels.c
+++ b/channels.c
@@ -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
@@ -3407,11 +3407,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)
diff --git a/channels.h b/channels.h
index 3054b04df..bb2650f6b 100644
--- a/channels.h
+++ b/channels.h
@@ -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>
@@ -170,6 +170,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;