diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/drm/drm_drv.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index 77e2fb7b7b37..0e7af53c87de 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c | |||
@@ -495,23 +495,25 @@ int drm_ioctl(struct inode *inode, struct file *filp, | |||
495 | } else { | 495 | } else { |
496 | if (cmd & (IOC_IN | IOC_OUT)) { | 496 | if (cmd & (IOC_IN | IOC_OUT)) { |
497 | kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); | 497 | kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); |
498 | if (!kdata) | 498 | if (!kdata) { |
499 | return -ENOMEM; | 499 | retcode = -ENOMEM; |
500 | goto err_i1; | ||
501 | } | ||
500 | } | 502 | } |
501 | 503 | ||
502 | if (cmd & IOC_IN) { | 504 | if (cmd & IOC_IN) { |
503 | if (copy_from_user(kdata, (void __user *)arg, | 505 | if (copy_from_user(kdata, (void __user *)arg, |
504 | _IOC_SIZE(cmd)) != 0) { | 506 | _IOC_SIZE(cmd)) != 0) { |
505 | retcode = -EACCES; | 507 | retcode = -EFAULT; |
506 | goto err_i1; | 508 | goto err_i1; |
507 | } | 509 | } |
508 | } | 510 | } |
509 | retcode = func(dev, kdata, file_priv); | 511 | retcode = func(dev, kdata, file_priv); |
510 | 512 | ||
511 | if (cmd & IOC_OUT) { | 513 | if ((retcode == 0) && (cmd & IOC_OUT)) { |
512 | if (copy_to_user((void __user *)arg, kdata, | 514 | if (copy_to_user((void __user *)arg, kdata, |
513 | _IOC_SIZE(cmd)) != 0) | 515 | _IOC_SIZE(cmd)) != 0) |
514 | retcode = -EACCES; | 516 | retcode = -EFAULT; |
515 | } | 517 | } |
516 | } | 518 | } |
517 | 519 | ||