/* This is a very simplified version of CVE-2017-18549, a use of uninitialized padding values affecting the Linux kernel (and thus GPLv2). It was fixed by e.g. 342ffc26693b528648bdc9377e51e4f2450b4860 on linux-4.13.y in linux-stable. */ #include "analyzer-decls.h" #include typedef unsigned int __u32; typedef unsigned int u32; typedef unsigned char u8; /* Adapted from include/uapi/linux/types.h */ #define __bitwise typedef __u32 __bitwise __le32; /* Adapted from drivers/scsi/aacraid/aacraid.h */ #define AAC_SENSE_BUFFERSIZE 30 struct aac_srb_reply { __le32 status; __le32 srb_status; __le32 scsi_status; __le32 data_xfer_length; __le32 sense_data_size; u8 sense_data[AAC_SENSE_BUFFERSIZE]; /* Manually added to help verify the fix. */ u8 padding[2]; }; #define ST_OK 0 #define SRB_STATUS_SUCCESS 0x01 extern void check_uninit (u8 v); /* Adapted from drivers/scsi/aacraid/commctrl.c */ static int aac_send_raw_srb(/* [...snip...] */) { u32 byte_count = 0; /* [...snip...] */ struct aac_srb_reply reply; reply.status = ST_OK; /* [...snip...] */ reply.srb_status = SRB_STATUS_SUCCESS; reply.scsi_status = 0; reply.data_xfer_length = byte_count; reply.sense_data_size = 0; memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE); /* [...snip...] */ __analyzer_eval (reply.status == ST_OK); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.srb_status == SRB_STATUS_SUCCESS); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.scsi_status == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.data_xfer_length == byte_count); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.sense_data_size == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.sense_data[0] == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.sense_data[AAC_SENSE_BUFFERSIZE - 1] == 0); /* { dg-warning "TRUE" } */ check_uninit (reply.padding[0]); /* { dg-warning "uninitialized value" } */ check_uninit (reply.padding[1]); /* { dg-warning "uninitialized value" } */ } static int aac_send_raw_srb_fixed(/* [...snip...] */) { u32 byte_count = 0; /* [...snip...] */ struct aac_srb_reply reply; /* This is the fix. */ memset(&reply, 0, sizeof(reply)); reply.status = ST_OK; /* [...snip...] */ reply.srb_status = SRB_STATUS_SUCCESS; reply.scsi_status = 0; reply.data_xfer_length = byte_count; reply.sense_data_size = 0; memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE); /* [...snip...] */ __analyzer_eval (reply.status == ST_OK); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.srb_status == SRB_STATUS_SUCCESS); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.scsi_status == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.data_xfer_length == byte_count); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.sense_data_size == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.sense_data[0] == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.sense_data[AAC_SENSE_BUFFERSIZE - 1] == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.padding[0] == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.padding[1] == 0); /* { dg-warning "TRUE" } */ }