"Das U-Boot" Source Tree
at master 71 lines 2.0 kB view raw
1/* SPDX-License-Identifier: GPL-2.0+ */ 2/* 3 * Copyright (c) 2022 Google, Inc. 4 * Written by Andrew Scull <ascull@google.com> 5 */ 6 7#include <dm.h> 8#include <virtio.h> 9#include <virtio_ring.h> 10#include <test/fuzz.h> 11 12static int fuzz_vring(const uint8_t *data, size_t size) 13{ 14 struct udevice *bus, *dev; 15 struct virtio_dev_priv *uc_priv; 16 struct virtqueue *vq; 17 struct virtio_sg sg[2]; 18 struct virtio_sg *sgs[2]; 19 unsigned int len; 20 u8 buffer[2][32]; 21 22 /* hackily hardcode vring sizes */ 23 size_t num = 4; 24 size_t desc_size = (sizeof(struct vring_desc) * num); 25 size_t avail_size = (3 + num) * sizeof(u16); 26 size_t used_size = (3 * sizeof(u16)) + (sizeof(struct vring_used_elem) * num); 27 28 if (size < (desc_size + avail_size + used_size)) 29 return 0; 30 31 /* check probe success */ 32 if (uclass_first_device_err(UCLASS_VIRTIO, &bus)) 33 panic("Could not find virtio bus\n"); 34 35 /* check the child virtio-rng device is bound */ 36 if (device_find_first_child(bus, &dev) || !dev) 37 panic("Could not find virtio device\n"); 38 39 /* 40 * fake the virtio device probe by filling in uc_priv->vdev 41 * which is used by virtio_find_vqs/virtio_del_vqs. 42 */ 43 uc_priv = dev_get_uclass_priv(bus); 44 uc_priv->vdev = dev; 45 46 /* prepare the scatter-gather buffer */ 47 sg[0].addr = buffer[0]; 48 sg[0].length = sizeof(buffer[0]); 49 sg[1].addr = buffer[1]; 50 sg[1].length = sizeof(buffer[1]); 51 sgs[0] = &sg[0]; 52 sgs[1] = &sg[1]; 53 54 if (virtio_find_vqs(dev, 1, &vq)) 55 panic("Could not find vqs\n"); 56 if (virtqueue_add(vq, sgs, 0, 1)) 57 panic("Could not add to virtqueue\n"); 58 /* Simulate device writing to vring */ 59 memcpy(vq->vring.desc, data, desc_size); 60 memcpy(vq->vring.avail, data + desc_size, avail_size); 61 memcpy(vq->vring.used, data + desc_size + avail_size, used_size); 62 /* Make sure there is a response */ 63 if (vq->vring.used->idx == 0) 64 vq->vring.used->idx = 1; 65 virtqueue_get_buf(vq, &len); 66 if (virtio_del_vqs(dev)) 67 panic("Could not delete vqs\n"); 68 69 return 0; 70} 71FUZZ_TEST(fuzz_vring, 0);