On Mi, 2016-02-17 at 13:55 +0530, P J P wrote:
> +-- On Tue, 16 Feb 2016, Gerd Hoffmann wrote --+
> | > @@ -172,11 +172,18 @@ static void do_token_in(USBDevice *s, USBPacket *p)
> | >      assert(p->ep->nr == 0);
> | > +    if (s->setup_len > sizeof(s->data_buf)) {
> | > +        fprintf(stderr,
> | > +                "usb_generic_handle_packet: ctrl buffer too small (%d > 
> %zu)\n",
> | > +                s->setup_len, sizeof(s->data_buf));
> | > +        p->status = USB_RET_STALL;
> | > +        return;
> | > +    }
> | 
> | Why this is needed?  All control transfers go through do_token_setup
> | first, so with the check moved in do_token_setup we should never ever
> | trigger it here ...
> 
>   usb_handle_packet
>    -> usb_process_one
>     -> do_token_in
> 
>   Is it possible for a guest to call do_token_in, without calling 
> do_token_setup first?

For anything interesting to happen in do_token_in() setup_state must be
set to either ACK or DATA, and for that to be the case do_token_setup()
must run first.  I don't think the guest can trick qemu to go straight
to do_token_in().

Also s->setup_len is set in do_token_setup() only, verifying it once
(after setting it from guest-supplied data) should be enough.

cheers,
  Gerd


Reply via email to