On Mon, 2 Nov 2026 at 13:36, Peter Maydell <[email protected]> wrote:
>
> From: Sergey Kambalin <[email protected]>
>
> Implement the receive DMA ring handling: qemu_can_receive()/
> receive() callbacks for the NIC's netdev peer, copying incoming
> frame data into descriptor buffers on the active RX ring,
> classifying broadcast/multicast, and raising the RXDMA_MBDONE
> interrupt as descriptors complete.

Coverity suggests that the handling of lengths in the receive
code here may not be right (CID 1690161); Marcelo, could you
have a look, please?

> +    while (len < size) {
> +        size_t l = size - len;
> +        size_t buf_size = MIN(ring->ring_buf_size & 0xffff,
> +                              sizeof(s->rx_packet));
> +        uint8_t *dma_buf = s->rx_packet;
> +        hwaddr dma_buf_addr =
> +            bcm2838_genet_make_u64(desc->address_hi, desc->address_lo);
> +        MemTxResult mem_tx_result = MEMTX_OK;
> +        const size_t frame_off = sizeof(BCM2838GenetXmitStatus) + 2;

Here we calculate a frame_off assuming we have the xmit status
struct and another 2 bytes as well as the payload...

> +        uint8_t *frame_buf = dma_buf + frame_off;
> +
> +        bool crc_fwd = FIELD_EX32(s->regs.umac.cmd, GENET_UMAC_CMD, CRC_FWD);
> +        size_t buflength;
> +        uint32_t prod_index;
> +
> +        if (l > ring->ring_buf_size) {
> +            l = ring->ring_buf_size;
> +        }
> +        /* Never copy more than fits in rx_packet after the status block */
> +        if (l > sizeof(s->rx_packet) - frame_off) {
> +            l = sizeof(s->rx_packet) - frame_off;
> +        }

...and here we drop the amount of payload to allow for that...

> +
> +        memcpy(frame_buf, buf + len, l);
> +
> +        len += l;
> +
> +        desc->length_status = FIELD_DP32(desc->length_status,
> +                                         GENET_RDMA_LENGTH_STATUS,
> +                                         EOP, !!(len >= size));
> +
> +        buflength = l + sizeof(BCM2838GenetXmitStatus) + 2;
> +        if (crc_fwd) {
> +            buflength += 4;
> +        }

...but here we calculate buflen with payload + struct + 2 +
also potentially an extra 4 for the CRC. Shouldn't we have
allowed for the CRC in the earlier calculations somehow too?

> +
> +        desc->length_status = FIELD_DP32(desc->length_status,
> +                                         GENET_RDMA_LENGTH_STATUS,
> +                                         BUFLENGTH, buflength);

The thing Coverity thinks happens is that buflength might not
fit in the 12 bit descriptor field.

thanks
-- PMM

Reply via email to