(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
plugin/
infoleak-CVE-2014-1446-1.c
       1  /* "The yam_ioctl function in drivers/net/hamradio/yam.c in the Linux kernel
       2     before 3.12.8 does not initialize a certain structure member, which allows
       3     local users to obtain sensitive information from kernel memory by
       4     leveraging the CAP_NET_ADMIN capability for an SIOCYAMGCFG ioctl call."
       5  
       6     Fixed e.g. by e7834c71c2cacc621ddc64bd71f83ef2054f6539 on linux-3.12.y
       7     in linux-stable.  */
       8  
       9  #include <string.h>
      10  
      11  #include "test-uaccess.h"
      12  
      13  /* Adapted from include/linux/yam.h  */
      14  
      15  struct yamcfg {
      16  	unsigned int mask;		/* Mask of commands */
      17  	unsigned int iobase;	/* IO Base of COM port */
      18  	unsigned int irq;		/* IRQ of COM port */
      19  	unsigned int bitrate;	/* Bit rate of radio port */
      20  	unsigned int baudrate;	/* Baud rate of the RS232 port */
      21  	unsigned int txdelay;	/* TxDelay */
      22  	unsigned int txtail;	/* TxTail */
      23  	unsigned int persist;	/* Persistence */
      24  	unsigned int slottime;	/* Slottime */
      25  	unsigned int mode;		/* mode 0 (simp), 1(Dupl), 2(Dupl+delay) */
      26  	unsigned int holddly;	/* PTT delay in FullDuplex 2 mode */
      27  };
      28  
      29  struct yamdrv_ioctl_cfg {
      30  	int cmd; /* { dg-message "field 'cmd' is uninitialized \\(4 bytes\\)" } */
      31  	struct yamcfg cfg;
      32  };
      33  
      34  /* Adapted from include/asm-generic/errno-base.h  */
      35  
      36  #define	EFAULT		14	/* Bad address */
      37  
      38  /* Adapted from drivers/net/hamradio/yam.c  */
      39  
      40  struct yam_port {
      41  	/* [...snip...] */
      42  
      43  	int bitrate;
      44  	int baudrate;
      45  	int iobase;
      46  	int irq;
      47  	int dupmode;
      48  
      49  	/* [...snip...] */
      50  
      51  	int txd;				/* tx delay */
      52  	int holdd;				/* duplex ptt delay */
      53  	int txtail;				/* txtail delay */
      54  	int slot;				/* slottime */
      55  	int pers;				/* persistence */
      56  
      57  	/* [...snip...] */
      58  };
      59  
      60  /* Broken version, leaving yi.cmd uninitialized.  */
      61  
      62  static int yam_ioctl(/* [...snip...] */
      63  		     void __user *dst, struct yam_port *yp)
      64  {
      65  	struct yamdrv_ioctl_cfg yi; /* { dg-message "region created on stack here" "memspace event" } */
      66  	/* { dg-message "capacity: 48 bytes" "capacity event" { target *-*-* } .-1 } */
      67  
      68  	/* [...snip...] */
      69  
      70  	/* case SIOCYAMGCFG: */
      71  		yi.cfg.mask = 0xffffffff;
      72  		yi.cfg.iobase = yp->iobase;
      73  		yi.cfg.irq = yp->irq;
      74  		yi.cfg.bitrate = yp->bitrate;
      75  		yi.cfg.baudrate = yp->baudrate;
      76  		yi.cfg.mode = yp->dupmode;
      77  		yi.cfg.txdelay = yp->txd;
      78  		yi.cfg.holddly = yp->holdd;
      79  		yi.cfg.txtail = yp->txtail;
      80  		yi.cfg.persist = yp->pers;
      81  		yi.cfg.slottime = yp->slot;
      82  		if (copy_to_user(dst, &yi, sizeof(struct yamdrv_ioctl_cfg))) /* { dg-warning "potential exposure of sensitive information by copying uninitialized data from stack" "warning" } */
      83  			/* { dg-message "4 bytes are uninitialized" "how much note" { target *-*-* } .-1 } */
      84  			 return -EFAULT;
      85  	/* [...snip...] */
      86  
      87  	return 0;
      88  }
      89  
      90  /* Fixed version, with a memset.  */
      91  
      92  static int yam_ioctl_fixed(/* [...snip...] */
      93  			   void __user *dst, struct yam_port *yp)
      94  {
      95  	struct yamdrv_ioctl_cfg yi;
      96  
      97  	/* [...snip...] */
      98  
      99  	/* case SIOCYAMGCFG: */
     100  		memset(&yi, 0, sizeof(yi));
     101  		yi.cfg.mask = 0xffffffff;
     102  		yi.cfg.iobase = yp->iobase;
     103  		yi.cfg.irq = yp->irq;
     104  		yi.cfg.bitrate = yp->bitrate;
     105  		yi.cfg.baudrate = yp->baudrate;
     106  		yi.cfg.mode = yp->dupmode;
     107  		yi.cfg.txdelay = yp->txd;
     108  		yi.cfg.holddly = yp->holdd;
     109  		yi.cfg.txtail = yp->txtail;
     110  		yi.cfg.persist = yp->pers;
     111  		yi.cfg.slottime = yp->slot;
     112  		if (copy_to_user(dst, &yi, sizeof(struct yamdrv_ioctl_cfg))) /* { dg-bogus "" } */
     113  			 return -EFAULT;
     114  	/* [...snip...] */
     115  
     116  	return 0;
     117  }