1  /* "An issue was discovered in drivers/scsi/aacraid/commctrl.c in the
       2     Linux kernel before 4.13. There is potential exposure of kernel stack
       3     memory because aac_send_raw_srb does not initialize the reply structure."
       4  
       5     Fixed e.g. by 342ffc26693b528648bdc9377e51e4f2450b4860 on linux-4.13.y 
       6     in linux-stable.
       7  
       8     This is a very simplified version of that code (before and after the fix). */
       9  
      10  /* { dg-do compile } */
      11  /* { dg-options "-fanalyzer" } */
      12  /* { dg-require-effective-target analyzer } */
      13  /* { dg-skip-if "structure layout assumption not met" { default_packed } } */
      14  
      15  #include <string.h>
      16  
      17  typedef unsigned int __u32;
      18  typedef unsigned int u32;
      19  typedef unsigned char u8;
      20  
      21  #include "test-uaccess.h"
      22  
      23  /* Adapted from include/uapi/linux/types.h  */
      24  
      25  #define __bitwise
      26  typedef __u32 __bitwise __le32;
      27  
      28  /* Adapted from drivers/scsi/aacraid/aacraid.h  */
      29  
      30  #define		AAC_SENSE_BUFFERSIZE	 30
      31  
      32  struct aac_srb_reply
      33  {
      34  	__le32		status;
      35  	__le32		srb_status;
      36  	__le32		scsi_status;
      37  	__le32		data_xfer_length;
      38  	__le32		sense_data_size;
      39  	u8		sense_data[AAC_SENSE_BUFFERSIZE]; /* { dg-message "padding after field 'sense_data' is uninitialized \\(2 bytes\\)" } */
      40  };
      41  
      42  #define		ST_OK		0
      43  #define SRB_STATUS_SUCCESS                  0x01
      44  
      45  /* Adapted from drivers/scsi/aacraid/commctrl.c  */
      46  
      47  static int aac_send_raw_srb(/* [...snip...] */
      48  			    void __user *user_reply)
      49  {
      50  	u32 byte_count = 0;
      51  
      52  	/* [...snip...] */
      53  
      54  	struct aac_srb_reply reply; /* { dg-message "region created on stack here" "memspace message" } */
      55  	/* { dg-message "capacity: 52 bytes" "capacity message" { target *-*-* } .-1 } */
      56  
      57  	reply.status = ST_OK;
      58  		
      59  	/* [...snip...] */
      60  
      61  	reply.srb_status = SRB_STATUS_SUCCESS;
      62  	reply.scsi_status = 0;
      63  	reply.data_xfer_length = byte_count;
      64  	reply.sense_data_size = 0;
      65  	memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE);
      66  
      67  	/* [...snip...] */
      68  
      69  	if (copy_to_user(user_reply, &reply, /* { dg-warning "potential exposure of sensitive information by copying uninitialized data from stack" } */
      70  					     /* { dg-message "2 bytes are uninitialized" "note how much" { target *-*-* } .-1 } */
      71  			 sizeof(struct aac_srb_reply))) {
      72  		/* [...snip...] */
      73  	}
      74  	/* [...snip...] */
      75  }
      76  
      77  static int aac_send_raw_srb_fixed(/* [...snip...] */
      78  				  void __user *user_reply)
      79  {
      80  	u32 byte_count = 0;
      81  
      82  	/* [...snip...] */
      83  
      84  	struct aac_srb_reply reply;
      85  
      86  	/* This is the fix.  */
      87  	memset(&reply, 0, sizeof(reply));
      88  
      89  	reply.status = ST_OK;
      90  		
      91  	/* [...snip...] */
      92  
      93  	reply.srb_status = SRB_STATUS_SUCCESS;
      94  	reply.scsi_status = 0;
      95  	reply.data_xfer_length = byte_count;
      96  	reply.sense_data_size = 0;
      97  	memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE);
      98  
      99  	/* [...snip...] */
     100  
     101  	if (copy_to_user(user_reply, &reply, /* { dg-bogus "" } */
     102  			 sizeof(struct aac_srb_reply))) {
     103  		/* [...snip...] */
     104  	}
     105  	/* [...snip...] */
     106  }