Download Exploit (password zimperium_ndays)
Vulnerable file drivers/video/tegra/host/bus_client.c
The function nvhost_init_error_notifier does not validate args->offset which is from userland, so it can lead to arbitrary kernel write.
| static int nvhost_init_error_notifier(struct nvhost_channel *ch, |
| struct nvhost_set_error_notifier *args) { |
| void *va; |
| struct dma_buf *dmabuf; |
| if (!args->mem) { |
| dev_err(&ch->dev->dev, "invalid memory handle\n"); |
| return -EINVAL; |
| } |
| dmabuf = dma_buf_get(args->mem); |
| if (ch->error_notifier_ref) |
| nvhost_free_error_notifiers(ch); |
| if (IS_ERR(dmabuf)) { |
| dev_err(&ch->dev->dev, "Invalid handle: %d\n", args->mem); |
| return -EINVAL; |
| } |
| /* map handle */ |
| va = dma_buf_vmap(dmabuf); |
| if (!va) { |
| dma_buf_put(dmabuf); |
| dev_err(&ch->dev->dev, "Cannot map notifier handle\n"); |
| return -ENOMEM; |
| } |
| /* set channel notifiers pointer */ |
| ch->error_notifier_ref = dmabuf; |
| ch->error_notifier = va + args->offset; |
| ch->error_notifier_va = va; |
| memset(ch->error_notifier, 0, sizeof(struct nvhost_notification)); |
| return 0; |
| } |