1  /* This is a very simplified version of CVE-2017-18549,
       2     a use of uninitialized padding values affecting the Linux kernel
       3     (and thus GPLv2).
       4  
       5     It was fixed by e.g. 342ffc26693b528648bdc9377e51e4f2450b4860 on linux-4.13.y
       6     in linux-stable.  */
       7  
       8  /* { dg-additional-options "-fno-analyzer-suppress-followups" } */
       9  
      10  #include "analyzer-decls.h"
      11  #include <string.h>
      12  
      13  typedef unsigned int __u32;
      14  typedef unsigned int u32;
      15  typedef unsigned char u8;
      16  
      17  /* Adapted from include/uapi/linux/types.h  */
      18  
      19  #define __bitwise
      20  typedef __u32 __bitwise __le32;
      21  
      22  /* Adapted from drivers/scsi/aacraid/aacraid.h  */
      23  
      24  #define		AAC_SENSE_BUFFERSIZE	 30
      25  
      26  struct aac_srb_reply
      27  {
      28  	__le32		status;
      29  	__le32		srb_status;
      30  	__le32		scsi_status;
      31  	__le32		data_xfer_length;
      32  	__le32		sense_data_size;
      33  	u8		sense_data[AAC_SENSE_BUFFERSIZE];
      34  
      35  	/* Manually added to help verify the fix.  */
      36  	u8 padding[2];
      37  };
      38  
      39  #define		ST_OK		0
      40  #define SRB_STATUS_SUCCESS                  0x01
      41  
      42  extern void check_uninit (u8 v);
      43  
      44  /* Adapted from drivers/scsi/aacraid/commctrl.c  */
      45  
      46  static int aac_send_raw_srb(/* [...snip...] */)
      47  {
      48  	u32 byte_count = 0;
      49  
      50  	/* [...snip...] */
      51  
      52  	struct aac_srb_reply reply; /* { dg-message "region created on stack here" } */
      53  
      54  	reply.status = ST_OK;
      55  
      56  	/* [...snip...] */
      57  
      58  	reply.srb_status = SRB_STATUS_SUCCESS;
      59  	reply.scsi_status = 0;
      60  	reply.data_xfer_length = byte_count;
      61  	reply.sense_data_size = 0;
      62  	memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE);
      63  
      64  	/* [...snip...] */
      65  
      66  	__analyzer_eval (reply.status == ST_OK); /* { dg-warning "TRUE" } */
      67  	__analyzer_eval (reply.srb_status == SRB_STATUS_SUCCESS); /* { dg-warning "TRUE" } */
      68  	__analyzer_eval (reply.scsi_status == 0); /* { dg-warning "TRUE" } */
      69  	__analyzer_eval (reply.data_xfer_length == byte_count); /* { dg-warning "TRUE" } */
      70  	__analyzer_eval (reply.sense_data_size == 0); /* { dg-warning "TRUE" } */
      71  	__analyzer_eval (reply.sense_data[0] == 0); /* { dg-warning "TRUE" } */
      72  	__analyzer_eval (reply.sense_data[AAC_SENSE_BUFFERSIZE - 1] == 0); /* { dg-warning "TRUE" } */
      73  	check_uninit (reply.padding[0]); /* { dg-warning "uninitialized value" } */
      74  	check_uninit (reply.padding[1]); /* { dg-warning "uninitialized value" } */
      75  }
      76  
      77  static int aac_send_raw_srb_fixed(/* [...snip...] */)
      78  {
      79  	u32 byte_count = 0;
      80  
      81  	/* [...snip...] */
      82  
      83  	struct aac_srb_reply reply;
      84  
      85  	/* This is the fix.  */
      86  	memset(&reply, 0, sizeof(reply));
      87  
      88  	reply.status = ST_OK;
      89  
      90  	/* [...snip...] */
      91  
      92  	reply.srb_status = SRB_STATUS_SUCCESS;
      93  	reply.scsi_status = 0;
      94  	reply.data_xfer_length = byte_count;
      95  	reply.sense_data_size = 0;
      96  	memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE);
      97  
      98  	/* [...snip...] */
      99  
     100  	__analyzer_eval (reply.status == ST_OK); /* { dg-warning "TRUE" } */
     101  	__analyzer_eval (reply.srb_status == SRB_STATUS_SUCCESS); /* { dg-warning "TRUE" } */
     102  	__analyzer_eval (reply.scsi_status == 0); /* { dg-warning "TRUE" } */
     103  	__analyzer_eval (reply.data_xfer_length == byte_count); /* { dg-warning "TRUE" } */
     104  	__analyzer_eval (reply.sense_data_size == 0); /* { dg-warning "TRUE" } */
     105  	__analyzer_eval (reply.sense_data[0] == 0); /* { dg-warning "TRUE" } */
     106  	__analyzer_eval (reply.sense_data[AAC_SENSE_BUFFERSIZE - 1] == 0); /* { dg-warning "TRUE" } */
     107  	__analyzer_eval (reply.padding[0] == 0); /* { dg-warning "TRUE" } */
     108  	__analyzer_eval (reply.padding[1] == 0); /* { dg-warning "TRUE" } */
     109  }