forked from Minki/linux
drm/exynos: g2d: prevent integer overflow in
The size computations done in the ioctl function use an integer. If userspace submits a request with req->cmd_nr or req->cmd_buf_nr set to INT_MAX, the integer computations overflow later, leading to potential (kernel) memory corruption. Prevent this issue by enforcing a limit on the number of submitted commands, so that we have enough headroom later for the size computations. Note that this change has no impact on the currently available users in userspace, like e.g. libdrm/exynos. While at it, also make a comment about the size computation more detailed. Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
parent
8646dcb8a0
commit
e41456bfc8
@ -1193,6 +1193,17 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
|
||||
if (!node)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* To avoid an integer overflow for the later size computations, we
|
||||
* enforce a maximum number of submitted commands here. This limit is
|
||||
* sufficient for all conceivable usage cases of the G2D.
|
||||
*/
|
||||
if (req->cmd_nr > G2D_CMDLIST_DATA_NUM ||
|
||||
req->cmd_buf_nr > G2D_CMDLIST_DATA_NUM) {
|
||||
dev_err(dev, "number of submitted G2D commands exceeds limit\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
node->event = NULL;
|
||||
|
||||
if (req->event_type != G2D_EVENT_NOT) {
|
||||
@ -1250,7 +1261,11 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
|
||||
cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF;
|
||||
}
|
||||
|
||||
/* Check size of cmdlist: last 2 is about G2D_BITBLT_START */
|
||||
/*
|
||||
* Check the size of cmdlist. The 2 that is added last comes from
|
||||
* the implicit G2D_BITBLT_START that is appended once we have
|
||||
* checked all the submitted commands.
|
||||
*/
|
||||
size = cmdlist->last + req->cmd_nr * 2 + req->cmd_buf_nr * 2 + 2;
|
||||
if (size > G2D_CMDLIST_DATA_NUM) {
|
||||
dev_err(dev, "cmdlist size is too big\n");
|
||||
|
Loading…
Reference in New Issue
Block a user