Proto device is not thread safe. Its `ioctl` handler in particular exposes multiple exploitable race condition bugs (such as double free UaF).
None of the commands take locks, leading to multiple race condition bugs. For example, `PROTO_IOC_BUSDMA_MEM_FREE` command presents double linked list removal and double free race conditions, since it leads to calling `proto_busdma_md_destroy_internal` with no locks taken:
static int
proto_busdma_md_destroy_internal(struct proto_busdma *busdma,
struct proto_md *md)
{
LIST_REMOVE(md, mds);
LIST_REMOVE(md, peers);
if (md->physaddr)
bus_dmamap_unload(md->bd_tag, md->bd_map);
if (md->virtaddr != NULL)
bus_dmamem_free(md->bd_tag, md->virtaddr, md->bd_map);
else
bus_dmamap_destroy(md->bd_tag, md->bd_map);
bus_dma_tag_destroy(md->bd_tag);
free(md, M_PROTO_BUSDMA);
return (0);
}
Since this device is created with permission `0666`, these bugs can be used for privilege escalation.
This can be fixed by taking the giant mutex on all method calls, by adding the `D_NEEDGIANT` flag.