lib/libvfio-user.c
/*
* Ideally, if argsz is too small for the bitmap, we should set argsz in the
* reply and fail the request with a struct vfio_user_dma_unmap payload.
* Instead, we simply fail the request - that's what VFIO does anyway.
*/
Ideally, if argsz is too small for the bitmap, we should set argsz in the
reply and fail the request with a struct vfio_user_dma_unmap payload.
Instead, we simply fail the request - that's what VFIO does anyway.
Ideally if argsz is too small for the bitmap we should set argsz in the reply and fail the request with a struct vfio_user_dma_unmap payload . Instead we simply fail the request - that ' s what VFIO does anyway .
static bool
is_valid_unmap(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg,
               struct vfio_user_dma_unmap *dma_unmap)
{
    size_t struct_size = sizeof(*dma_unmap);
    size_t min_argsz = sizeof(*dma_unmap);
    switch (dma_unmap->flags) {
    case VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP:
        struct_size += sizeof(*dma_unmap->bitmap);
        min_argsz = satadd_u64(struct_size, dma_unmap->bitmap->size);
        break;
    case VFIO_DMA_UNMAP_FLAG_ALL:
        if (dma_unmap->addr || dma_unmap->size) {
            vfu_log(vfu_ctx, LOG_ERR, "bad addr=%#lx or size=%#lx, expected "
                    "both to be zero", dma_unmap->addr, dma_unmap->size);
            errno = EINVAL;
            return false;
        }
        break;
    case 0:
        break;
    default:
        vfu_log(vfu_ctx, LOG_ERR, "invalid DMA flags=%#x", dma_unmap->flags);
        errno = EINVAL;
        return false;
    }
    if (msg->in.iov.iov_len < struct_size ||
        dma_unmap->argsz < min_argsz ||
        dma_unmap->argsz > SERVER_MAX_DATA_XFER_SIZE) {
        vfu_log(vfu_ctx, LOG_ERR, "bad DMA unmap region size=%zu argsz=%u",
                msg->in.iov.iov_len, dma_unmap->argsz);
        errno = EINVAL;
        return false;
    }
    return true;
}
static bool is_valid_unmap ( vfu_ctx_t * vfu_ctx , vfu_msg_t * msg , struct vfio_user_dma_unmap * dma_unmap ) { size_t struct_size = sizeof ( * dma_unmap ) ; size_t min_argsz = sizeof ( * dma_unmap ) ; switch ( dma_unmap -> flags ) { case VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP : struct_size += sizeof ( * dma_unmap -> bitmap ) ; min_argsz = satadd_u64 ( struct_size , dma_unmap -> bitmap -> size ) ; break ; case VFIO_DMA_UNMAP_FLAG_ALL : if ( dma_unmap -> addr || dma_unmap -> size ) { vfu_log ( vfu_ctx , LOG_ERR , " " " " , dma_unmap -> addr , dma_unmap -> size ) ; errno = EINVAL ; return false ; } break ; case 0 : break ; default : vfu_log ( vfu_ctx , LOG_ERR , " " , dma_unmap -> flags ) ; errno = EINVAL ; return false ; } if ( msg -> in . iov . iov_len < struct_size || dma_unmap -> argsz < min_argsz || dma_unmap -> argsz > SERVER_MAX_DATA_XFER_SIZE ) { vfu_log ( vfu_ctx , LOG_ERR , " " , msg -> in . iov . iov_len , dma_unmap -> argsz ) ; errno = EINVAL ; return false ; } return true ; }
Ideally, if argsz is too small for the bitmap, we should set argsz in the
reply and fail the request with a struct vfio_user_dma_unmap payload.
Ideally if argsz is too small for the bitmap we should set argsz in the reply and fail the request with a struct vfio_user_dma_unmap payload .
/*
         * Because the saturating add will ensure that any overflow will be
         * larger than the maximum allowed ->argsz, this is sufficient to check
         * for that (which we need, because we are about to allocate based upon
         * this value).
         */