From 1e76f61bb001b93795a227f8f808104b6c10b048 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 8 Aug 2012 13:24:21 -0600 Subject: msm: kgsl: Detect and avoid malformed ioctl codes Because we were using _IO_NR, one could construct a malformed ioctl code that would avoid allocating memory yet go to a function that expected that memory. Still use _IO_NR to index the array of ioctls, but check that the full values match before jumping to the helper function. CRs-fixed: 385592 Change-Id: Ic0dedbaded469035bd0a2bb0f20fecb2a3045ca5 Signed-off-by: Jordan Crouse --- drivers/gpu/msm/kgsl.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 57a0e2b..53eff77 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -2176,7 +2176,7 @@ static const struct { static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { struct kgsl_device_private *dev_priv = filep->private_data; - unsigned int nr = _IOC_NR(cmd); + unsigned int nr; kgsl_ioctl_func_t func; int lock, ret; char ustack[64]; @@ -2192,6 +2192,8 @@ static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) else if (cmd == IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_OLD) cmd = IOCTL_KGSL_CMDSTREAM_READTIMESTAMP; + nr = _IOC_NR(cmd); + if (cmd & (IOC_IN | IOC_OUT)) { if (_IOC_SIZE(cmd) < sizeof(ustack)) uptr = ustack; @@ -2216,7 +2218,20 @@ static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) } if (nr < ARRAY_SIZE(kgsl_ioctl_funcs) && - kgsl_ioctl_funcs[nr].func != NULL) { + kgsl_ioctl_funcs[nr].func != NULL) { + + /* + * Make sure that nobody tried to send us a malformed ioctl code + * with a valid NR but bogus flags + */ + + if (kgsl_ioctl_funcs[nr].cmd != cmd) { + KGSL_DRV_ERR(dev_priv->device, + "Malformed ioctl code %08x\n", cmd); + ret = -ENOIOCTLCMD; + goto done; + } + func = kgsl_ioctl_funcs[nr].func; lock = kgsl_ioctl_funcs[nr].lock; } else { -- cgit v1.1