summaryrefslogtreecommitdiffstats
path: root/daemon/device.c
diff options
context:
space:
mode:
authorGravatar Hector Martin2010-01-23 23:09:43 +0100
committerGravatar Hector Martin2010-01-24 00:20:01 +0100
commitc0b02222fd85feabb0b9901364082dc6ab484b68 (patch)
treee465e0a29a24431c67feb35529912214f8d1308f /daemon/device.c
parent68729a347011a8fb39f1e4aa35ae06c4f2f491d4 (diff)
downloadusbmuxd-c0b02222fd85feabb0b9901364082dc6ab484b68.tar.gz
usbmuxd-c0b02222fd85feabb0b9901364082dc6ab484b68.tar.bz2
Clean up packet size types and add some paranoia
None of this should fix an exploit, it's just healthy paranoia.
Diffstat (limited to 'daemon/device.c')
-rw-r--r--daemon/device.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/daemon/device.c b/daemon/device.c
index 7cda462..759cb91 100644
--- a/daemon/device.c
+++ b/daemon/device.c
@@ -38,7 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
38 38
39int next_device_id; 39int next_device_id;
40 40
41#define DEV_PKTBUF_SIZE 65536 41#define DEV_MRU 65536
42 42
43#define CONN_INBUF_SIZE 262144 43#define CONN_INBUF_SIZE 262144
44#define CONN_OUTBUF_SIZE 65536 44#define CONN_OUTBUF_SIZE 65536
@@ -90,13 +90,13 @@ struct mux_connection
90 uint32_t tx_seq, tx_ack, tx_acked, tx_win; 90 uint32_t tx_seq, tx_ack, tx_acked, tx_win;
91 uint32_t rx_seq, rx_recvd, rx_ack, rx_win; 91 uint32_t rx_seq, rx_recvd, rx_ack, rx_win;
92 int max_payload; 92 int max_payload;
93 int sendable; 93 uint32_t sendable;
94 int flags; 94 int flags;
95 unsigned char *ib_buf; 95 unsigned char *ib_buf;
96 int ib_size; 96 uint32_t ib_size;
97 int ib_capacity; 97 uint32_t ib_capacity;
98 unsigned char *ob_buf; 98 unsigned char *ob_buf;
99 int ob_capacity; 99 uint32_t ob_capacity;
100 short events; 100 short events;
101 uint64_t last_ack_time; 101 uint64_t last_ack_time;
102}; 102};
@@ -109,7 +109,7 @@ struct mux_device
109 struct collection connections; 109 struct collection connections;
110 uint16_t next_sport; 110 uint16_t next_sport;
111 unsigned char *pktbuf; 111 unsigned char *pktbuf;
112 int pktlen; 112 uint32_t pktlen;
113}; 113};
114 114
115static struct collection device_list; 115static struct collection device_list;
@@ -404,7 +404,7 @@ void device_client_process(int device_id, struct mux_client *client, short event
404 update_connection(conn); 404 update_connection(conn);
405} 405}
406 406
407static void connection_device_input(struct mux_connection *conn, unsigned char *payload, int payload_length) 407static void connection_device_input(struct mux_connection *conn, unsigned char *payload, uint32_t payload_length)
408{ 408{
409 if((conn->ib_size + payload_length) > conn->ib_capacity) { 409 if((conn->ib_size + payload_length) > conn->ib_capacity) {
410 usbmuxd_log(LL_ERROR, "Input buffer overflow on device %d connection %d->%d (space=%d, payload=%d)", conn->dev->id, conn->sport, conn->dport, conn->ib_capacity-conn->ib_size, payload_length); 410 usbmuxd_log(LL_ERROR, "Input buffer overflow on device %d connection %d->%d (space=%d, payload=%d)", conn->dev->id, conn->sport, conn->dport, conn->ib_capacity-conn->ib_size, payload_length);
@@ -459,7 +459,7 @@ static void device_version_input(struct mux_device *dev, struct version_header *
459 client_device_add(&info); 459 client_device_add(&info);
460} 460}
461 461
462static void device_tcp_input(struct mux_device *dev, struct tcphdr *th, unsigned char *payload, int payload_length) 462static void device_tcp_input(struct mux_device *dev, struct tcphdr *th, unsigned char *payload, uint32_t payload_length)
463{ 463{
464 usbmuxd_log(LL_DEBUG, "[IN] dev=%d sport=%d dport=%d seq=%d ack=%d flags=0x%x window=%d[%d] len=%d", 464 usbmuxd_log(LL_DEBUG, "[IN] dev=%d sport=%d dport=%d seq=%d ack=%d flags=0x%x window=%d[%d] len=%d",
465 dev->id, ntohs(th->th_sport), ntohs(th->th_dport), ntohl(th->th_seq), ntohl(th->th_ack), th->th_flags, ntohs(th->th_win) << 8, ntohs(th->th_win), payload_length); 465 dev->id, ntohs(th->th_sport), ntohs(th->th_dport), ntohl(th->th_seq), ntohl(th->th_ack), th->th_flags, ntohs(th->th_win) << 8, ntohs(th->th_win), payload_length);
@@ -531,7 +531,7 @@ static void device_tcp_input(struct mux_device *dev, struct tcphdr *th, unsigned
531 } 531 }
532} 532}
533 533
534void device_data_input(struct usb_device *usbdev, unsigned char *buffer, int length) 534void device_data_input(struct usb_device *usbdev, unsigned char *buffer, uint32_t length)
535{ 535{
536 struct mux_device *dev = NULL; 536 struct mux_device *dev = NULL;
537 FOREACH(struct mux_device *tdev, &device_list) { 537 FOREACH(struct mux_device *tdev, &device_list) {
@@ -548,11 +548,17 @@ void device_data_input(struct usb_device *usbdev, unsigned char *buffer, int len
548 if(!length) 548 if(!length)
549 return; 549 return;
550 550
551 // sanity check (should never happen with current USB implementation)
552 if((length > USB_MRU) || (length > DEV_MRU)) {
553 usbmuxd_log(LL_ERROR, "Too much data received from USB (%d), file a bug", length);
554 return;
555 }
556
551 usbmuxd_log(LL_SPEW, "Mux data input for device %p: %p len %d", dev, buffer, length); 557 usbmuxd_log(LL_SPEW, "Mux data input for device %p: %p len %d", dev, buffer, length);
552 558
553 // handle broken up transfers 559 // handle broken up transfers
554 if(dev->pktlen) { 560 if(dev->pktlen) {
555 if((length + dev->pktlen) > DEV_PKTBUF_SIZE) { 561 if((length + dev->pktlen) > DEV_MRU) {
556 usbmuxd_log(LL_ERROR, "Incoming split packet is too large (%d so far), dropping!", length + dev->pktlen); 562 usbmuxd_log(LL_ERROR, "Incoming split packet is too large (%d so far), dropping!", length + dev->pktlen);
557 dev->pktlen = 0; 563 dev->pktlen = 0;
558 return; 564 return;
@@ -588,13 +594,21 @@ void device_data_input(struct usb_device *usbdev, unsigned char *buffer, int len
588 594
589 struct tcphdr *th; 595 struct tcphdr *th;
590 unsigned char *payload; 596 unsigned char *payload;
591 int payload_length; 597 uint32_t payload_length;
592 598
593 switch(ntohl(mhdr->protocol)) { 599 switch(ntohl(mhdr->protocol)) {
594 case MUX_PROTO_VERSION: 600 case MUX_PROTO_VERSION:
601 if(length < (sizeof(struct mux_header) + sizeof(struct version_header))) {
602 usbmuxd_log(LL_ERROR, "Incoming version packet is too small (%d)", length);
603 return;
604 }
595 device_version_input(dev, (struct version_header *)(mhdr+1)); 605 device_version_input(dev, (struct version_header *)(mhdr+1));
596 break; 606 break;
597 case MUX_PROTO_TCP: 607 case MUX_PROTO_TCP:
608 if(length < (sizeof(struct mux_header) + sizeof(struct tcphdr))) {
609 usbmuxd_log(LL_ERROR, "Incoming TCP packet is too small (%d)", length);
610 return;
611 }
598 th = (struct tcphdr *)(mhdr+1); 612 th = (struct tcphdr *)(mhdr+1);
599 payload = (unsigned char *)(th+1); 613 payload = (unsigned char *)(th+1);
600 payload_length = length - sizeof(struct tcphdr) - sizeof(struct mux_header); 614 payload_length = length - sizeof(struct tcphdr) - sizeof(struct mux_header);
@@ -618,7 +632,7 @@ int device_add(struct usb_device *usbdev)
618 dev->usbdev = usbdev; 632 dev->usbdev = usbdev;
619 dev->state = MUXDEV_INIT; 633 dev->state = MUXDEV_INIT;
620 dev->next_sport = 1; 634 dev->next_sport = 1;
621 dev->pktbuf = malloc(DEV_PKTBUF_SIZE); 635 dev->pktbuf = malloc(DEV_MRU);
622 dev->pktlen = 0; 636 dev->pktlen = 0;
623 struct version_header vh; 637 struct version_header vh;
624 vh.major = htonl(1); 638 vh.major = htonl(1);