From 2eb4611de8eb1fc874b59b757abfe90b30851d1f Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Wed, 29 Jun 2011 05:00:56 -0500 Subject: [PATCH] ppp: Add basic length sanity checks --- gatchat/gatppp.c | 9 +++++---- gatchat/ppp.h | 6 ++++-- gatchat/ppp_auth.c | 10 ++++++++-- gatchat/ppp_cp.c | 4 ++-- gatchat/ppp_cp.h | 2 +- gatchat/ppp_net.c | 10 ++++++++-- 6 files changed, 28 insertions(+), 13 deletions(-) diff --git a/gatchat/gatppp.c b/gatchat/gatppp.c index 84b43388..2ff6c86b 100644 --- a/gatchat/gatppp.c +++ b/gatchat/gatppp.c @@ -214,17 +214,18 @@ static void ppp_receive(const unsigned char *buf, gsize len, void *data) switch (protocol) { case PPP_IP_PROTO: - ppp_net_process_packet(ppp->net, packet); + ppp_net_process_packet(ppp->net, packet, len - offset); break; case LCP_PROTOCOL: - pppcp_process_packet(ppp->lcp, packet); + pppcp_process_packet(ppp->lcp, packet, len - offset); break; case IPCP_PROTO: - pppcp_process_packet(ppp->ipcp, packet); + pppcp_process_packet(ppp->ipcp, packet, len - offset); break; case CHAP_PROTOCOL: if (ppp->chap) { - ppp_chap_process_packet(ppp->chap, packet); + ppp_chap_process_packet(ppp->chap, packet, + len - offset); break; } /* fall through */ diff --git a/gatchat/ppp.h b/gatchat/ppp.h index fcd7aa8a..afcee53d 100644 --- a/gatchat/ppp.h +++ b/gatchat/ppp.h @@ -98,12 +98,14 @@ void ipcp_set_server_info(struct pppcp_data *ipcp, guint32 peer_addr, /* CHAP related functions */ struct ppp_chap *ppp_chap_new(GAtPPP *ppp, guint8 method); void ppp_chap_free(struct ppp_chap *chap); -void ppp_chap_process_packet(struct ppp_chap *chap, const guint8 *new_packet); +void ppp_chap_process_packet(struct ppp_chap *chap, const guint8 *new_packet, + gsize len); /* TUN / Network related functions */ struct ppp_net *ppp_net_new(GAtPPP *ppp, int fd); const char *ppp_net_get_interface(struct ppp_net *net); -void ppp_net_process_packet(struct ppp_net *net, const guint8 *packet); +void ppp_net_process_packet(struct ppp_net *net, const guint8 *packet, + gsize len); void ppp_net_free(struct ppp_net *net); gboolean ppp_net_set_mtu(struct ppp_net *net, guint16 mtu); void ppp_net_suspend_interface(struct ppp_net *net); diff --git a/gatchat/ppp_auth.c b/gatchat/ppp_auth.c index 4ad31a2c..0f8cffab 100644 --- a/gatchat/ppp_auth.c +++ b/gatchat/ppp_auth.c @@ -118,9 +118,15 @@ challenge_out: /* * parse the packet */ -void ppp_chap_process_packet(struct ppp_chap *chap, const guint8 *new_packet) +void ppp_chap_process_packet(struct ppp_chap *chap, const guint8 *new_packet, + gsize len) { - guint8 code = new_packet[0]; + guint8 code; + + if (len < sizeof(struct chap_header)) + return; + + code = new_packet[0]; switch (code) { case CHALLENGE: diff --git a/gatchat/ppp_cp.c b/gatchat/ppp_cp.c index bef83d2c..05f5a76b 100644 --- a/gatchat/ppp_cp.c +++ b/gatchat/ppp_cp.c @@ -945,7 +945,7 @@ void pppcp_send_protocol_reject(struct pppcp_data *data, /* * parse the packet and determine which event this packet caused */ -void pppcp_process_packet(gpointer priv, const guint8 *new_packet) +void pppcp_process_packet(gpointer priv, const guint8 *new_packet, gsize len) { struct pppcp_data *data = priv; const struct pppcp_packet *packet = @@ -953,7 +953,7 @@ void pppcp_process_packet(gpointer priv, const guint8 *new_packet) guint8 event_type; guint data_len = 0; - if (data == NULL) + if (len < sizeof(struct pppcp_packet)) return; /* check flags to see if we support this code */ diff --git a/gatchat/ppp_cp.h b/gatchat/ppp_cp.h index edcc996d..26404738 100644 --- a/gatchat/ppp_cp.h +++ b/gatchat/ppp_cp.h @@ -117,7 +117,7 @@ void pppcp_set_local_options(struct pppcp_data *data, const guint8 *options, guint16 len); -void pppcp_process_packet(gpointer priv, const guint8 *new_packet); +void pppcp_process_packet(gpointer priv, const guint8 *new_packet, gsize len); void pppcp_send_protocol_reject(struct pppcp_data *data, const guint8 *rejected_packet, gsize len); void pppcp_signal_open(struct pppcp_data *data); diff --git a/gatchat/ppp_net.c b/gatchat/ppp_net.c index 7ce7bc81..edce8366 100644 --- a/gatchat/ppp_net.c +++ b/gatchat/ppp_net.c @@ -77,16 +77,22 @@ gboolean ppp_net_set_mtu(struct ppp_net *net, guint16 mtu) return TRUE; } -void ppp_net_process_packet(struct ppp_net *net, const guint8 *packet) +void ppp_net_process_packet(struct ppp_net *net, const guint8 *packet, + gsize plen) { GIOStatus status; gsize bytes_written; guint16 len; + if (plen < 4) + return; + /* find the length of the packet to transmit */ len = get_host_short(&packet[2]); status = g_io_channel_write_chars(net->channel, (gchar *) packet, - len, &bytes_written, NULL); + MIN(len, plen), + &bytes_written, NULL); + if (status != G_IO_STATUS_NORMAL) return; }