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.