• Stefan Haberland's avatar
    s390/dasd: fix using offset into zero size array error · 6fb7b213
    Stefan Haberland authored
    BugLink: https://bugs.launchpad.net/bugs/1822271
    
    [ Upstream commit 4a8ef699 ]
    
    Dan Carpenter reported the following:
    
    The patch 52898025: "[S390] dasd: security and PSF update patch
    for EMC CKD ioctl" from Mar 8, 2010, leads to the following static
    checker warning:
    
    	drivers/s390/block/dasd_eckd.c:4486 dasd_symm_io()
    	error: using offset into zero size array 'psf_data[]'
    
    drivers/s390/block/dasd_eckd.c
      4458          /* Copy parms from caller */
      4459          rc = -EFAULT;
      4460          if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
                                        ^^^^^^^
    The user can specify any "usrparm.psf_data_len".  They choose zero by
    mistake.
    
      4461                  goto out;
      4462          if (is_compat_task()) {
      4463                  /* Make sure pointers are sane even on 31 bit. */
      4464                  rc = -EINVAL;
      4465                  if ((usrparm.psf_data >> 32) != 0)
      4466                          goto out;
      4467                  if ((usrparm.rssd_result >> 32) != 0)
      4468                          goto out;
      4469                  usrparm.psf_data &= 0x7fffffffULL;
      4470                  usrparm.rssd_result &= 0x7fffffffULL;
      4471          }
      4472          /* alloc I/O data area */
      4473          psf_data = kzalloc(usrparm.psf_data_len, GFP_KERNEL
      			   				 | GFP_DMA);
      4474          rssd_result = kzalloc(usrparm.rssd_result_len, GFP_KERNEL
    							       | GFP_DMA);
      4475          if (!psf_data || !rssd_result) {
    
    kzalloc() returns a ZERO_SIZE_PTR (0x16).
    
      4476                  rc = -ENOMEM;
      4477                  goto out_free;
      4478          }
      4479
      4480          /* get syscall header from user space */
      4481          rc = -EFAULT;
      4482          if (copy_from_user(psf_data,
      4483                             (void __user *)(unsigned long)
      				   	 		 usrparm.psf_data,
      4484                             usrparm.psf_data_len))
    
    That all works great.
    
      4485                  goto out_free;
      4486          psf0 = psf_data[0];
      4487          psf1 = psf_data[1];
    
    But now we're assuming that "->psf_data_len" was at least 2 bytes.
    
    Fix this by checking the user specified length psf_data_len.
    
    Fixes: 52898025 ("[S390] dasd: security and PSF update patch for EMC CKD ioctl")
    Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
    Signed-off-by: default avatarStefan Haberland <sth@linux.ibm.com>
    Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
    Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
    Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
    Acked-by: default avatarJuerg Haefliger <juerg.haefliger@canonical.com>
    Signed-off-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
    6fb7b213
dasd_eckd.c 143 KB