1  /* { dg-do compile } */
       2  // TODO: remove need for -fanalyzer-checker=taint here:
       3  /* { dg-options "-fanalyzer -fanalyzer-checker=taint" } */
       4  /* { dg-require-effective-target analyzer } */
       5  
       6  /* See notes in this header.  */
       7  #include "taint-CVE-2011-0521.h"
       8  
       9  /* Adapted from drivers/media/dvb/ttpci/av7110_ca.c  */
      10  
      11  int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg)
      12  {
      13  	struct dvb_device *dvbdev = file->private_data;
      14  	struct av7110 *av7110 = dvbdev->priv;
      15  	unsigned long arg = (unsigned long) parg;
      16  
      17  	/* case CA_GET_SLOT_INFO:  */
      18  	{
      19  		ca_slot_info_t *info=(ca_slot_info_t *)parg;
      20  
      21  		if (info->num > 1)
      22  			return -EINVAL;
      23  		av7110->ci_slot[info->num].num = info->num; /* { dg-warning "attacker-controlled value" "" { xfail *-*-* } } */
      24  		// TODO(xfail)
      25  		av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
      26  							CA_CI_LINK : CA_CI;
      27  		memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t));
      28  	}
      29  	return 0;
      30  }
      31  
      32  /* Adapted from drivers/media/dvb/dvb-core/dvbdev.c
      33     Further simplified from -2; always use an on-stack buffer.  */
      34  
      35  static DEFINE_MUTEX(dvbdev_mutex);
      36  
      37  int dvb_usercopy(struct file *file,
      38  		 unsigned int cmd, unsigned long arg)
      39  {
      40  	char    sbuf[128];
      41  	void    *parg = sbuf;
      42  	int     err = -EFAULT;
      43  	if (copy_from_user(parg, (void __user *)arg, sizeof(sbuf)))
      44  	  goto out;
      45  
      46  	mutex_lock(&dvbdev_mutex);
      47  	if ((err = dvb_ca_ioctl(file, cmd, parg)) == -ENOIOCTLCMD)
      48  		err = -EINVAL;
      49  	mutex_unlock(&dvbdev_mutex);
      50  
      51  	if (err < 0)
      52  		goto out;
      53  
      54  	if (copy_to_user((void __user *)arg, parg, sizeof(sbuf)))
      55  	  err = -EFAULT;
      56  
      57  out:
      58  	return err;
      59  }