Ejemplo n.º 1
0
static void jig_response_complete(struct usb_ep *ep, struct usb_request *req)
{
  struct psfreedom_device *dev = ep->driver_data;
  int status = req->status;
  unsigned long flags;

  spin_lock_irqsave (&dev->lock, flags);
  DBG (dev, "Jig response sent (status %d). Sent data so far : %d + %d\n",
      status, dev->response_len, req->length);

  switch (status) {
    case 0:				/* normal completion */
      if (ep == dev->in_ep) {
        /* our transmit completed.
           see if there's more to go.
           hub_transmit eats req, don't queue it again. */
        dev->response_len += req->length;
        if (dev->response_len < 64) {
          jig_response_send (dev, req);
        } else {
          dev->status = DEVICE5_READY;
          SET_TIMER (150);
        }
        spin_unlock_irqrestore (&dev->lock, flags);
        return;
      }
      break;

      /* this endpoint is normally active while we're configured */
    case -ECONNABORTED:		/* hardware forced ep reset */
    case -ESHUTDOWN:		/* disconnect from host */
      VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status,
          req->actual, req->length);
    case -ECONNRESET:		/* request dequeued */
      hub_interrupt_queued = 0;
      spin_unlock_irqrestore (&dev->lock, flags);
      return;

    case -EOVERFLOW:		/* buffer overrun on read means that
                                 * we didn't provide a big enough
                                 * buffer.
                                 */
    default:
      DBG(dev, "%s complete --> %d, %d/%d\n", ep->name,
          status, req->actual, req->length);
      break;
    case -EREMOTEIO:		/* short read */
      break;
  }

  status = usb_ep_queue(ep, req, GFP_ATOMIC);
  if (status) {
    ERROR(dev, "kill %s:  resubmit %d bytes --> %d\n",
        ep->name, req->length, status);
    usb_ep_set_halt(ep);
    /* FIXME recover later ... somehow */
  }
  spin_unlock_irqrestore (&dev->lock, flags);
}
Ejemplo n.º 2
0
static void psfreedom_state_machine_timeout(unsigned long data)
{
  struct usb_gadget *gadget = (struct usb_gadget *)data;
  struct psfreedom_device *dev = get_gadget_data (gadget);
  unsigned long flags;

  spin_lock_irqsave (&dev->lock, flags);
  DBG (dev, "Timer fired, status is %s\n", STATUS_STR (dev->status));

  /* We need to delay switching the address because otherwise we will respond
     to the request (that triggered the port switch) with address 0. So we need
     to reply with the hub's address, THEN switch to 0.
  */
  if (dev->switch_to_port_delayed >= 0)
    switch_to_port (dev, dev->switch_to_port_delayed);
  dev->switch_to_port_delayed = -1;

  switch (dev->status) {
    case HUB_READY:
      dev->status = DEVICE1_WAIT_READY;
      hub_connect_port (dev, 1);
      break;
    case DEVICE1_READY:
      dev->status = DEVICE2_WAIT_READY;
      hub_connect_port (dev, 2);
      break;
    case DEVICE2_READY:
      dev->status = DEVICE3_WAIT_READY;
      hub_connect_port (dev, 3);
      break;
    case DEVICE3_READY:
      dev->status = DEVICE2_WAIT_DISCONNECT;
      hub_disconnect_port (dev, 2);
      break;
    case DEVICE2_DISCONNECTED:
      dev->status = DEVICE4_WAIT_READY;
      hub_connect_port (dev, 4);
      break;
    case DEVICE4_READY:
      dev->status = DEVICE5_WAIT_READY;
      hub_connect_port (dev, 5);
      break;
    case DEVICE5_CHALLENGED:
      jig_response_send (dev, NULL);
      break;
    case DEVICE5_READY:
#ifdef NO_DELAYED_PORT_SWITCHING
      /* if we can't delay the port switching, then we at this point, we can't
         disconnect the device 3... so we just unregister the driver so that
         all the devices get virtually disconnected and the exploit works.
         Since we won't exist after that, let's unlock the spinlock and return.
      */
      spin_unlock_irqrestore (&dev->lock, flags);
      dev->status = DONE;
      psfreedom_cleanup ();
      return;
#else
      dev->status = DEVICE3_WAIT_DISCONNECT;
      hub_disconnect_port (dev, 3);
#endif
      break;
    case DEVICE3_DISCONNECTED:
      dev->status = DEVICE5_WAIT_DISCONNECT;
      /* If not using JIG mode, then no need to unplug the JIG, since we'll
         need to keep it in memory so we can find its address from an lv2 dump
       */
#ifdef USE_JIG
      hub_disconnect_port (dev, 5);
#endif
      break;
    case DEVICE5_DISCONNECTED:
      dev->status = DEVICE4_WAIT_DISCONNECT;
      hub_disconnect_port (dev, 4);
      break;
    case DEVICE4_DISCONNECTED:
      dev->status = DEVICE1_WAIT_DISCONNECT;
      hub_disconnect_port (dev, 1);
      break;
    case DEVICE1_DISCONNECTED:
      /* simple check to see if a stage2 is loaded */
      if (dev->stage2_payload) {
        dev->status = DEVICE6_WAIT_READY;
        hub_connect_port (dev, 6);
      } else {
        dev->status = DONE;
        INFO (dev, "JAILBROKEN!!! DONE!!!!!!!!!\n");
        INFO (dev, "Congratulations, worked!");
        del_timer (&psfreedom_state_machine_timer);
        timer_added = 0;
      }
      break;
    default:
      break;
  }
  spin_unlock_irqrestore (&dev->lock, flags);

}
Ejemplo n.º 3
0
static void psfreedom_state_machine_timeout(unsigned long data)
{
    struct usb_gadget *gadget = (struct usb_gadget *)data;
    struct psfreedom_device *dev = get_gadget_data (gadget);
    unsigned long flags;

    spin_lock_irqsave (&dev->lock, flags);
    DBG (dev, "Timer fired, status is %s\n", STATUS_STR (dev->status));

    /* We need to delay switching the address because otherwise we will respond
       to the request (that triggered the port switch) with address 0. So we need
       to reply with the hub's address, THEN switch to 0.
    */
    if (dev->switch_to_port_delayed >= 0)
        switch_to_port (dev, dev->switch_to_port_delayed);
    dev->switch_to_port_delayed = -1;

    switch (dev->status) {
    case HUB_READY:
        dev->status = DEVICE1_WAIT_READY;
        hub_connect_port (dev, 1);
        break;
    case DEVICE1_READY:
        dev->status = DEVICE2_WAIT_READY;
        hub_connect_port (dev, 2);
        break;
    case DEVICE2_READY:
        dev->status = DEVICE3_WAIT_READY;
        hub_connect_port (dev, 3);
        break;
    case DEVICE3_READY:
        dev->status = DEVICE2_WAIT_DISCONNECT;
        hub_disconnect_port (dev, 2);
        break;
    case DEVICE2_DISCONNECTED:
        dev->status = DEVICE4_WAIT_READY;
        hub_connect_port (dev, 4);
        break;
    case DEVICE4_READY:
        dev->status = DEVICE5_WAIT_READY;
        hub_connect_port (dev, 5);
        break;
    case DEVICE5_CHALLENGED:
        jig_response_send (dev, NULL);
        break;
    case DEVICE5_READY:
        dev->status = DEVICE3_WAIT_DISCONNECT;
        hub_disconnect_port (dev, 3);
        break;
    case DEVICE3_DISCONNECTED:
        dev->status = DEVICE5_WAIT_DISCONNECT;
        hub_disconnect_port (dev, 5);
        break;
    case DEVICE5_DISCONNECTED:
        dev->status = DEVICE4_WAIT_DISCONNECT;
        hub_disconnect_port (dev, 4);
        break;
    case DEVICE4_DISCONNECTED:
        dev->status = DEVICE1_WAIT_DISCONNECT;
        hub_disconnect_port (dev, 1);
        break;
    case DEVICE1_DISCONNECTED:
        dev->status = DEVICE6_WAIT_READY;
        hub_connect_port (dev, 6);
        break;
    case DEVICE6_READY:
        dev->status = DONE;
        INFO (dev, "Congratulations, worked!");
        del_timer (&psfreedom_state_machine_timer);
        timer_added = 0;
        break;
    default:
        break;
    }
    spin_unlock_irqrestore (&dev->lock, flags);

}