aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-04-28 18:52:11 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-04-28 18:52:11 -0700
commitcf681c2ebcb502ced998ca0659b2907b9ad9daf9 (patch)
treee7a0176be1f9bb9bffc686cc3472034f6abd07f4 /drivers
parentb75a2bf899b668b1d52de8846aafdbcf81349c73 (diff)
parent532c34b5fbf1687df63b3fcd5b2846312ac943c6 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky: "Three more bug fixes for 4.6 - Due to a race in the dynamic page table code a multi-threaded program can cause a translation specification exception. With panic_on_oops a user space program can crash the system. - An information leak with the /dev/sclp device. - A use after free in the s390 PCI code" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/sclp_ctl: fix potential information leak with /dev/sclp s390/mm: fix asce_bits handling with dynamic pagetable levels s390/pci: fix use after free in dma_init
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/char/sclp_ctl.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/s390/char/sclp_ctl.c b/drivers/s390/char/sclp_ctl.c
index 648cb86afd42..ea607a4a1bdd 100644
--- a/drivers/s390/char/sclp_ctl.c
+++ b/drivers/s390/char/sclp_ctl.c
@@ -56,6 +56,7 @@ static int sclp_ctl_ioctl_sccb(void __user *user_area)
{
struct sclp_ctl_sccb ctl_sccb;
struct sccb_header *sccb;
+ unsigned long copied;
int rc;
if (copy_from_user(&ctl_sccb, user_area, sizeof(ctl_sccb)))
@@ -65,14 +66,15 @@ static int sclp_ctl_ioctl_sccb(void __user *user_area)
sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!sccb)
return -ENOMEM;
- if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sizeof(*sccb))) {
+ copied = PAGE_SIZE -
+ copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), PAGE_SIZE);
+ if (offsetof(struct sccb_header, length) +
+ sizeof(sccb->length) > copied || sccb->length > copied) {
rc = -EFAULT;
goto out_free;
}
- if (sccb->length > PAGE_SIZE || sccb->length < 8)
- return -EINVAL;
- if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sccb->length)) {
- rc = -EFAULT;
+ if (sccb->length < 8) {
+ rc = -EINVAL;
goto out_free;
}
rc = sclp_sync_request(ctl_sccb.cmdw, sccb);