From 04b6db55f20b7057a5503c0a9f348bfba66b44f7 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Wed, 10 Jul 2019 20:32:41 +0100 Subject: [PATCH] Honour the packet size limit in bare-connection protocol. When I set up the simplified version of just the ssh-connection protocol we use for connection sharing, I carefully documented at the top of sshshare.c that packets in that protocol variant are limited to just over 0x4000 bytes. And did I remember to actually honour that, by restricting the sizes of outgoing packets when actually speaking the bare connection protocol? I did not. Well, better late than never. Here I introduce a packet size limit that can be imposed by the BPP, and arrange for sshconnection.c to take the min of that and any given channel's max packet size as sent by the remote end. All BPPs except ssh2bpp-bare set it to the no-op value of the largest possible uint32_t. --- ssh1bpp.c | 1 + ssh2bpp-bare.c | 1 + ssh2bpp.c | 1 + ssh2connection.c | 4 ++++ sshbpp.h | 1 + sshverstring.c | 1 + 6 files changed, 9 insertions(+) diff --git a/ssh1bpp.c b/ssh1bpp.c index 77cec35f..f11e58cb 100644 --- a/ssh1bpp.c +++ b/ssh1bpp.c @@ -42,6 +42,7 @@ static const struct BinaryPacketProtocolVtable ssh1_bpp_vtable = { ssh1_bpp_handle_output, ssh1_bpp_new_pktout, ssh1_bpp_queue_disconnect, + 0xFFFFFFFF, /* no special packet size limit for this bpp */ }; BinaryPacketProtocol *ssh1_bpp_new(LogContext *logctx) diff --git a/ssh2bpp-bare.c b/ssh2bpp-bare.c index 44bb3332..8dc3b117 100644 --- a/ssh2bpp-bare.c +++ b/ssh2bpp-bare.c @@ -31,6 +31,7 @@ static const struct BinaryPacketProtocolVtable ssh2_bare_bpp_vtable = { ssh2_bare_bpp_handle_output, ssh2_bare_bpp_new_pktout, ssh2_bpp_queue_disconnect, /* in sshcommon.c */ + 0x4000, /* packet size limit, per protocol spec in sshshare.c comment */ }; BinaryPacketProtocol *ssh2_bare_bpp_new(LogContext *logctx) diff --git a/ssh2bpp.c b/ssh2bpp.c index 8b8ccc43..79b97b31 100644 --- a/ssh2bpp.c +++ b/ssh2bpp.c @@ -52,6 +52,7 @@ static const struct BinaryPacketProtocolVtable ssh2_bpp_vtable = { ssh2_bpp_handle_output, ssh2_bpp_new_pktout, ssh2_bpp_queue_disconnect, /* in sshcommon.c */ + 0xFFFFFFFF, /* no special packet size limit for this bpp */ }; BinaryPacketProtocol *ssh2_bpp_new( diff --git a/ssh2connection.c b/ssh2connection.c index 96191c70..78bb0ad6 100644 --- a/ssh2connection.c +++ b/ssh2connection.c @@ -421,6 +421,8 @@ static bool ssh2_connection_filter_queue(struct ssh2_connection_state *s) ssh2_channel_init(c); c->remwindow = winsize; c->remmaxpkt = pktsize; + if (c->remmaxpkt > s->ppl.bpp->vt->packet_size_limit) + c->remmaxpkt = s->ppl.bpp->vt->packet_size_limit; if (c->chan->initial_fixed_window_size) { c->locwindow = c->locmaxwin = c->remlocwin = c->chan->initial_fixed_window_size; @@ -487,6 +489,8 @@ static bool ssh2_connection_filter_queue(struct ssh2_connection_state *s) c->halfopen = false; c->remwindow = get_uint32(pktin); c->remmaxpkt = get_uint32(pktin); + if (c->remmaxpkt > s->ppl.bpp->vt->packet_size_limit) + c->remmaxpkt = s->ppl.bpp->vt->packet_size_limit; chan_open_confirmation(c->chan); diff --git a/sshbpp.h b/sshbpp.h index 8b3677c0..380c41a8 100644 --- a/sshbpp.h +++ b/sshbpp.h @@ -12,6 +12,7 @@ struct BinaryPacketProtocolVtable { PktOut *(*new_pktout)(int type); void (*queue_disconnect)(BinaryPacketProtocol *, const char *msg, int category); + uint32_t packet_size_limit; }; struct BinaryPacketProtocol { diff --git a/sshverstring.c b/sshverstring.c index 0b9152f3..4828c37b 100644 --- a/sshverstring.c +++ b/sshverstring.c @@ -51,6 +51,7 @@ static const struct BinaryPacketProtocolVtable ssh_verstring_vtable = { ssh_verstring_handle_output, ssh_verstring_new_pktout, ssh_verstring_queue_disconnect, + 0xFFFFFFFF, /* no special packet size limit for this bpp */ }; static void ssh_detect_bugs(struct ssh_verstring_state *s);