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; |
} |