diff options
author | djm@openbsd.org <djm@openbsd.org> | 2023-12-18 15:47:20 +0100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2023-12-18 15:52:55 +0100 |
commit | 0cb50eefdd29f0fec31d0e71cc4b004a5f704e67 (patch) | |
tree | 8bca2581bdf5d716cd55395c079167e9b708d58d /channels.c | |
parent | upstream: Make it possible to load certs from PKCS#11 tokens (diff) | |
download | openssh-0cb50eefdd29f0fec31d0e71cc4b004a5f704e67.tar.xz openssh-0cb50eefdd29f0fec31d0e71cc4b004a5f704e67.zip |
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
Diffstat (limited to 'channels.c')
-rw-r--r-- | channels.c | 19 |
1 files changed, 14 insertions, 5 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) |