diff options
Diffstat (limited to 'net/irda')
-rw-r--r-- | net/irda/ircomm/ircomm_core.c | 12 | ||||
-rw-r--r-- | net/irda/irlap_event.c | 13 |
2 files changed, 25 insertions, 0 deletions
diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c index 2d63fa8e1556..b825399fc160 100644 --- a/net/irda/ircomm/ircomm_core.c +++ b/net/irda/ircomm/ircomm_core.c @@ -363,6 +363,18 @@ void ircomm_process_data(struct ircomm_cb *self, struct sk_buff *skb) clen = skb->data[0]; /* + * Input validation check: a stir4200/mcp2150 combinations sometimes + * results in frames with clen > remaining packet size. These are + * illegal; if we throw away just this frame then it seems to carry on + * fine + */ + if (unlikely(skb->len < (clen + 1))) { + IRDA_DEBUG(2, "%s() throwing away illegal frame\n", + __FUNCTION__ ); + return; + } + + /* * If there are any data hiding in the control channel, we must * deliver it first. The side effect is that the control channel * will be removed from the skb diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c index 6d3aff862dc2..6af86eba7463 100644 --- a/net/irda/irlap_event.c +++ b/net/irda/irlap_event.c @@ -1199,6 +1199,19 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, switch (event) { case RECV_I_RSP: /* Optimize for the common case */ + if (unlikely(skb->len <= LAP_ADDR_HEADER + LAP_CTRL_HEADER)) { + /* + * Input validation check: a stir4200/mcp2150 + * combination sometimes results in an empty i:rsp. + * This makes no sense; we can just ignore the frame + * and send an rr:cmd immediately. This happens before + * changing nr or ns so triggers a retransmit + */ + irlap_wait_min_turn_around(self, &self->qos_tx); + irlap_send_rr_frame(self, CMD_FRAME); + /* Keep state */ + break; + } /* FIXME: must check for remote_busy below */ #ifdef CONFIG_IRDA_FAST_RR /* |