Exemple #1
0
static void psfreedom_setup_complete(struct usb_ep *ep, struct usb_request *req)
{
  struct psfreedom_device *dev = ep->driver_data;
  unsigned long flags;

  spin_lock_irqsave (&dev->lock, flags);
  if (req->status || req->actual != req->length) {
    struct psfreedom_device * dev = (struct psfreedom_device *) ep->driver_data;
    DBG(dev, "%s setup complete FAIL --> %d, %d/%d\n",
        STATUS_STR (dev->status), req->status, req->actual, req->length);
  } else {
    VDBG(dev, "%s setup complete SUCCESS --> %d, %d/%d\n",
        STATUS_STR (dev->status), req->status, req->actual, req->length);
  }
  spin_unlock_irqrestore (&dev->lock, flags);
}
Exemple #2
0
/*
 * The setup() callback implements all the ep0 functionality that's
 * not handled lower down, in hardware or the hardware driver (like
 * device and endpoint feature flags, and their status).  It's all
 * housekeeping for the gadget function we're implementing.  Most of
 * the work is in config-specific setup.
 */
static int psfreedom_setup(struct usb_gadget *gadget,
                           const struct usb_ctrlrequest *ctrl)
{
    struct psfreedom_device *dev = get_gadget_data(gadget);
    struct usb_request *req = dev->req;
    int value = -EOPNOTSUPP;
    u16 w_index = le16_to_cpu(ctrl->wIndex);
    u16 w_value = le16_to_cpu(ctrl->wValue);
    u16 w_length = le16_to_cpu(ctrl->wLength);
    u8 address = psfreedom_get_address (dev->gadget);
    unsigned long flags;
    u16 request = (ctrl->bRequestType << 8) | ctrl->bRequest;

    spin_lock_irqsave (&dev->lock, flags);
    VDBG (dev, "Setup called %d (%d) -- %d -- %d. Myaddr :%d\n", ctrl->bRequest,
          ctrl->bRequestType, w_value, w_index, address);

    req->zero = 0;

    /* Enable the timer if it's not already enabled */
    if (timer_added == 0)
        add_timer (&psfreedom_state_machine_timer);
    timer_added = 1;

    /* Set the address of the port */
    if (address)
        dev->port_address[dev->current_port] = address;

    /* Setup the hub or the devices */
    if (dev->current_port == 0)
        value = hub_setup (gadget, ctrl, request, w_index, w_value, w_length);
    else
        value = devices_setup (gadget, ctrl, request, w_index, w_value, w_length);

    DBG (dev, "%s Setup called %s (%d - %d) -> %d (w_length=%d)\n",
         STATUS_STR (dev->status),  REQUEST_STR (request), w_value, w_index,
         value, w_length);

    /* respond with data transfer before status phase? */
    if (value >= 0) {
        req->length = value;
        req->zero = value < w_length;
        value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
        if (value < 0) {
            DBG(dev, "ep_queue --> %d\n", value);
            req->status = 0;
            spin_unlock_irqrestore (&dev->lock, flags);
            psfreedom_setup_complete(gadget->ep0, req);
            return value;
        }
    }

    spin_unlock_irqrestore (&dev->lock, flags);
    /* device either stalls (value < 0) or reports success */
    return value;
}
Exemple #3
0
int proc_status_read(char *buffer, char **start, off_t offset, int count,
    int *eof, void *user_data)
{
  struct psfreedom_device *dev = user_data;
  unsigned int len;
  unsigned long flags;

  spin_lock_irqsave (&dev->lock, flags);
  INFO (dev, "proc_status_read (/proc/%s/%s) called. count %d\n",
      PROC_DIR_NAME, PROC_STATUS_NAME, count);

  *eof = 1;
  /* fill the buffer, return the buffer size */
  len = sprintf (buffer + offset, "%s\n", STATUS_STR (dev->status));

  spin_unlock_irqrestore (&dev->lock, flags);

  return len;
}
Exemple #4
0
int proc_status_read(char *buffer, char **start, off_t offset, int count,
    int *eof, void *user_data)
{
  struct psfreedom_device *dev = user_data;
  unsigned int len;
  unsigned long flags;

  spin_lock_irqsave (&dev->lock, flags);

  /* This file is meant to be read in a loop, so don't spam dmesg with an INFO
     message when it gets read */
  VDBG (dev, "proc_status_read (/proc/%s/%s) called. count %d\n",
      PROC_DIR_NAME, PROC_STATUS_NAME, count);

  *eof = 1;
  /* fill the buffer, return the buffer size */
  len = sprintf (buffer + offset, "%s\n", STATUS_STR (dev->status));

  spin_unlock_irqrestore (&dev->lock, flags);

  return len;
}
Exemple #5
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);

}
Exemple #6
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);

}