ppp: Add basic length sanity checks
authorDenis Kenzior <denkenz@gmail.com>
Wed, 29 Jun 2011 10:00:56 +0000 (05:00 -0500)
committerDenis Kenzior <denkenz@gmail.com>
Wed, 29 Jun 2011 10:00:56 +0000 (05:00 -0500)
gatchat/gatppp.c
gatchat/ppp.h
gatchat/ppp_auth.c
gatchat/ppp_cp.c
gatchat/ppp_cp.h
gatchat/ppp_net.c

index 84b4338..2ff6c86 100644 (file)
@@ -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 */
index fcd7aa8..afcee53 100644 (file)
@@ -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);
index 4ad31a2..0f8cffa 100644 (file)
@@ -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:
index bef83d2..05f5a76 100644 (file)
@@ -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 */
index edcc996..2640473 100644 (file)
@@ -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);
index 7ce7bc8..edce836 100644 (file)
@@ -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;
 }