r2axz / bluepill-serial-monster

USB to 3 Port Serial (UART) adapter firmware for STM32 Blue Pill.
MIT License
323 stars 76 forks source link

usb_send does not take into account usb_endpoints[ep_num].tx_size #52

Closed r2axz closed 2 years ago

r2axz commented 2 years ago
size_t usb_send(uint8_t ep_num, const void *buf, size_t count) {
    ep_reg_t *ep_reg = ep_regs(ep_num);
    usb_pbuffer_data_t *ep_buf = (usb_pbuffer_data_t *)(USB_PMAADDR + (usb_btable[ep_num].tx_offset<<1));
    pb_word_t *buf_p = (pb_word_t*)buf;
    pb_word_t words_left  = count >> 1;
    size_t tx_space_available = usb_endpoints[ep_num].tx_size;
    if (count > tx_space_available) {
        count = tx_space_available;
    }
    while (words_left--) {
        (ep_buf++)->data = *buf_p++;
    }
    if (count & 0x01) {
        (ep_buf)->data = (uint8_t)*buf_p;
    }
    usb_btable[ep_num].tx_count = count;
    *ep_reg = ((*ep_reg ^ USB_EP_TX_VALID) & (USB_EPREG_MASK | USB_EPTX_STAT)) | (USB_EP_CTR_RX | USB_EP_CTR_TX);
    return count;
}

words_left is initialized before count > tx_space_available check, which leads to writing past the ep tx buffer. Surprisingly, this does not cause any major problems because usb_send is mostly used during the device USB enumeration phase and its circular buffer sibling (usb_circ_buf_send) does not have this issue.