lkml.org 
[lkml]   [2016]   [Sep]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 158/192] s390/sclp_ctl: fix potential information leak with /dev/sclp
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Martin Schwidefsky <schwidefsky@de.ibm.com>

    commit 532c34b5fbf1687df63b3fcd5b2846312ac943c6 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: Pengfei Wang <wpengfeinudt@gmail.com>
    Reviewed-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
    Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
    Signed-off-by: Juerg Haefliger <juerg.haefliger@hpe.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/s390/char/sclp_ctl.c | 12 +++++++-----
    1 file changed, 7 insertions(+), 5 deletions(-)

    --- 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 __us
    {
    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 __us
    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);

    \
     
     \ /
      Last update: 2016-09-17 09:59    [W:6.181 / U:0.112 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site