(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
plugin/
taint-CVE-2011-0521-1.c
       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  		av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
      25  							CA_CI_LINK : CA_CI;
      26  		memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t));
      27  	}
      28  	return 0;
      29  }
      30  
      31  static struct dvb_device dvbdev_ca = {
      32  	.priv		= NULL,
      33  	/* [...snip...] */
      34  	.kernel_ioctl	= dvb_ca_ioctl,
      35  };
      36  
      37  /* Adapted from drivers/media/dvb/dvb-core/dvbdev.c  */
      38  
      39  static DEFINE_MUTEX(dvbdev_mutex);
      40  
      41  int dvb_usercopy(struct file *file,
      42  		     unsigned int cmd, unsigned long arg,
      43  		     int (*func)(struct file *file,
      44  		     unsigned int cmd, void *arg))
      45  {
      46  	char    sbuf[128];
      47  	void    *mbuf = NULL;
      48  	void    *parg = NULL;
      49  	int     err  = -1;
      50  
      51  	/*  Copy arguments into temp kernel buffer  */
      52  	switch (_IOC_DIR(cmd)) {
      53  	case _IOC_NONE:
      54  		/*
      55  		 * For this command, the pointer is actually an integer
      56  		 * argument.
      57  		 */
      58  		parg = (void *) arg;
      59  		break;
      60  	case _IOC_READ: /* some v4l ioctls are marked wrong ... */
      61  	case _IOC_WRITE:
      62  	case (_IOC_WRITE | _IOC_READ):
      63  		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
      64  			parg = sbuf;
      65  		} else {
      66  			/* too big to allocate from stack */
      67  			mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
      68  			if (NULL == mbuf)
      69  				return -ENOMEM;
      70  			parg = mbuf;
      71  		}
      72  
      73  		err = -EFAULT;
      74  		if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
      75  			goto out;
      76  		break;
      77  	}
      78  
      79  	/* call driver */
      80  	mutex_lock(&dvbdev_mutex);
      81  	if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD)
      82  		err = -EINVAL;
      83  	mutex_unlock(&dvbdev_mutex);
      84  
      85  	if (err < 0)
      86  		goto out;
      87  
      88  	/*  Copy results into user buffer  */
      89  	switch (_IOC_DIR(cmd))
      90  	{
      91  	case _IOC_READ:
      92  	case (_IOC_WRITE | _IOC_READ):
      93  		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
      94  			err = -EFAULT;
      95  		break;
      96  	}
      97  
      98  out:
      99  	kfree(mbuf);
     100  	return err;
     101  }
     102  
     103  long dvb_generic_ioctl(struct file *file,
     104  		       unsigned int cmd, unsigned long arg)
     105  {
     106  	struct dvb_device *dvbdev = file->private_data;
     107  
     108  	if (!dvbdev)
     109  		return -ENODEV;
     110  
     111  	if (!dvbdev->kernel_ioctl)
     112  		return -EINVAL;
     113  
     114  	return dvb_usercopy(file, cmd, arg, dvbdev->kernel_ioctl);
     115  }