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 #include "analyzer-decls.h" 9 #include <string.h> 10 11 typedef unsigned int __u32; 12 typedef unsigned int u32; 13 typedef unsigned char u8; 14 15 /* Adapted from include/uapi/linux/types.h */ 16 17 #define __bitwise 18 typedef __u32 __bitwise __le32; 19 20 /* Adapted from drivers/scsi/aacraid/aacraid.h */ 21 22 #define AAC_SENSE_BUFFERSIZE 30 23 24 struct aac_srb_reply 25 { 26 __le32 status; 27 __le32 srb_status; 28 __le32 scsi_status; 29 __le32 data_xfer_length; 30 __le32 sense_data_size; 31 u8 sense_data[AAC_SENSE_BUFFERSIZE]; 32 33 /* Manually added to help verify the fix. */ 34 u8 padding[2]; 35 }; 36 37 #define ST_OK 0 38 #define SRB_STATUS_SUCCESS 0x01 39 40 extern void check_uninit (u8 v); 41 42 /* Adapted from drivers/scsi/aacraid/commctrl.c */ 43 aac_send_raw_srb()44static int aac_send_raw_srb(/* [...snip...] */) 45 { 46 u32 byte_count = 0; 47 48 /* [...snip...] */ 49 50 struct aac_srb_reply reply; 51 52 reply.status = ST_OK; 53 54 /* [...snip...] */ 55 56 reply.srb_status = SRB_STATUS_SUCCESS; 57 reply.scsi_status = 0; 58 reply.data_xfer_length = byte_count; 59 reply.sense_data_size = 0; 60 memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE); 61 62 /* [...snip...] */ 63 64 __analyzer_eval (reply.status == ST_OK); /* { dg-warning "TRUE" } */ 65 __analyzer_eval (reply.srb_status == SRB_STATUS_SUCCESS); /* { dg-warning "TRUE" } */ 66 __analyzer_eval (reply.scsi_status == 0); /* { dg-warning "TRUE" } */ 67 __analyzer_eval (reply.data_xfer_length == byte_count); /* { dg-warning "TRUE" } */ 68 __analyzer_eval (reply.sense_data_size == 0); /* { dg-warning "TRUE" } */ 69 __analyzer_eval (reply.sense_data[0] == 0); /* { dg-warning "TRUE" } */ 70 __analyzer_eval (reply.sense_data[AAC_SENSE_BUFFERSIZE - 1] == 0); /* { dg-warning "TRUE" } */ 71 check_uninit (reply.padding[0]); /* { dg-warning "uninitialized value" } */ 72 check_uninit (reply.padding[1]); /* { dg-warning "uninitialized value" } */ 73 } 74 aac_send_raw_srb_fixed()75static int aac_send_raw_srb_fixed(/* [...snip...] */) 76 { 77 u32 byte_count = 0; 78 79 /* [...snip...] */ 80 81 struct aac_srb_reply reply; 82 83 /* This is the fix. */ 84 memset(&reply, 0, sizeof(reply)); 85 86 reply.status = ST_OK; 87 88 /* [...snip...] */ 89 90 reply.srb_status = SRB_STATUS_SUCCESS; 91 reply.scsi_status = 0; 92 reply.data_xfer_length = byte_count; 93 reply.sense_data_size = 0; 94 memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE); 95 96 /* [...snip...] */ 97 98 __analyzer_eval (reply.status == ST_OK); /* { dg-warning "TRUE" } */ 99 __analyzer_eval (reply.srb_status == SRB_STATUS_SUCCESS); /* { dg-warning "TRUE" } */ 100 __analyzer_eval (reply.scsi_status == 0); /* { dg-warning "TRUE" } */ 101 __analyzer_eval (reply.data_xfer_length == byte_count); /* { dg-warning "TRUE" } */ 102 __analyzer_eval (reply.sense_data_size == 0); /* { dg-warning "TRUE" } */ 103 __analyzer_eval (reply.sense_data[0] == 0); /* { dg-warning "TRUE" } */ 104 __analyzer_eval (reply.sense_data[AAC_SENSE_BUFFERSIZE - 1] == 0); /* { dg-warning "TRUE" } */ 105 __analyzer_eval (reply.padding[0] == 0); /* { dg-warning "TRUE" } */ 106 __analyzer_eval (reply.padding[1] == 0); /* { dg-warning "TRUE" } */ 107 } 108