Commit ffa7b15f authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Kamal Mostafa

s390/sclp_ctl: fix potential information leak with /dev/sclp

BugLink: http://bugs.launchpad.net/bugs/1624037

commit 532c34b5 upstream.

The sclp_ctl_ioctl_sccb function uses two copy_from_user calls to
retrieve the sclp request from user space. The first copy_from_user
fetches the length of the request which is stored in the first two
bytes of the request. The second copy_from_user gets the complete
sclp request, but this copies the length field a second time.
A malicious user may have changed the length in the meantime.
Reported-by: default avatarPengfei Wang <wpengfeinudt@gmail.com>
Reviewed-by: default avatarMichael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarJuerg Haefliger <juerg.haefliger@hpe.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarTim Gardner <tim.gardner@canonical.com>
Signed-off-by: default avatarKamal Mostafa <kamal@canonical.com>
parent 2002ae0c
...@@ -56,6 +56,7 @@ static int sclp_ctl_ioctl_sccb(void __user *user_area) ...@@ -56,6 +56,7 @@ static int sclp_ctl_ioctl_sccb(void __user *user_area)
{ {
struct sclp_ctl_sccb ctl_sccb; struct sclp_ctl_sccb ctl_sccb;
struct sccb_header *sccb; struct sccb_header *sccb;
unsigned long copied;
int rc; int rc;
if (copy_from_user(&ctl_sccb, user_area, sizeof(ctl_sccb))) 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) ...@@ -65,14 +66,15 @@ static int sclp_ctl_ioctl_sccb(void __user *user_area)
sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!sccb) if (!sccb)
return -ENOMEM; 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; rc = -EFAULT;
goto out_free; goto out_free;
} }
if (sccb->length > PAGE_SIZE || sccb->length < 8) if (sccb->length < 8) {
return -EINVAL; rc = -EINVAL;
if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sccb->length)) {
rc = -EFAULT;
goto out_free; goto out_free;
} }
rc = sclp_sync_request(ctl_sccb.cmdw, sccb); rc = sclp_sync_request(ctl_sccb.cmdw, sccb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment