libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / testsuite / gcc.dg / plugin / infoleak-CVE-2017-18550-1.c
blob449348a1017f828ae8dbcffed8fc528e3f980243
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_get_hba_info does not initialize the hbainfo structure."
5 Fixed e.g. by 342ffc26693b528648bdc9377e51e4f2450b4860 on linux-4.13.y
6 in linux-stable.
8 This is a simplified version of that code (before and after the fix). */
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 } } */
15 #include <string.h>
17 typedef unsigned int __u32;
18 typedef unsigned int u32;
19 typedef unsigned char u8;
21 #include "test-uaccess.h"
23 /* Adapted from include/uapi/linux/types.h */
25 #define __bitwise
26 typedef __u32 __bitwise __le32;
28 /* Adapted from drivers/scsi/aacraid/aacraid.h */
30 struct aac_hba_info {
32 u8 driver_name[50]; /* { dg-message "field 'driver_name' is uninitialized \\(50 bytes\\)" } */
33 u8 adapter_number;
34 u8 system_io_bus_number;
35 u8 device_number; /* { dg-message "padding after field 'device_number' is uninitialized \\(3 bytes\\)" } */
36 u32 function_number;
37 u32 vendor_id;
38 u32 device_id;
39 u32 sub_vendor_id;
40 u32 sub_system_id;
41 u32 mapped_base_address_size; /* { dg-message "field 'mapped_base_address_size' is uninitialized \\(4 bytes\\)" } */
42 u32 base_physical_address_high_part;
43 u32 base_physical_address_low_part;
45 u32 max_command_size;
46 u32 max_fib_size;
47 u32 max_scatter_gather_from_os;
48 u32 max_scatter_gather_to_fw;
49 u32 max_outstanding_fibs;
51 u32 queue_start_threshold;
52 u32 queue_dump_threshold;
53 u32 max_io_size_queued;
54 u32 outstanding_io;
56 u32 firmware_build_number;
57 u32 bios_build_number;
58 u32 driver_build_number;
59 u32 serial_number_high_part;
60 u32 serial_number_low_part;
61 u32 supported_options;
62 u32 feature_bits;
63 u32 currentnumber_ports;
65 u8 new_comm_interface:1; /* { dg-message "field 'new_comm_interface' is uninitialized \\(1 bit\\)" } */
66 u8 new_commands_supported:1;
67 u8 disable_passthrough:1;
68 u8 expose_non_dasd:1;
69 u8 queue_allowed:1;
70 u8 bled_check_enabled:1;
71 u8 reserved1:1;
72 u8 reserted2:1;
74 u32 reserved3[10]; /* { dg-message "field 'reserved3' is uninitialized \\(40 bytes\\)" } */
78 struct aac_dev
80 /* [...snip...] */
81 int id;
82 /* [...snip...] */
83 struct pci_dev *pdev; /* Our PCI interface */
84 /* [...snip...] */
87 /* Adapted from include/linux/pci.h */
89 struct pci_dev {
90 /* [...snip...] */
91 struct pci_bus *bus; /* bus this device is on */
92 /* [...snip...] */
93 unsigned int devfn; /* encoded device & function index */
94 unsigned short vendor;
95 unsigned short device;
96 unsigned short subsystem_vendor;
97 unsigned short subsystem_device;
98 /* [...snip...] */
101 struct pci_bus {
102 /* [...snip...] */
103 unsigned char number; /* bus number */
104 /* [...snip...] */
107 /* Adapted from drivers/scsi/aacraid/commctrl.c */
109 static int aac_get_hba_info(struct aac_dev *dev, void __user *arg)
111 struct aac_hba_info hbainfo; /* { dg-message "region created on stack here" "memspace message" } */
112 /* { dg-message "capacity: 200 bytes" "capacity message" { target *-*-* } .-1 } */
114 hbainfo.adapter_number = (u8) dev->id;
115 hbainfo.system_io_bus_number = dev->pdev->bus->number;
116 hbainfo.device_number = (dev->pdev->devfn >> 3);
117 hbainfo.function_number = (dev->pdev->devfn & 0x0007);
119 hbainfo.vendor_id = dev->pdev->vendor;
120 hbainfo.device_id = dev->pdev->device;
121 hbainfo.sub_vendor_id = dev->pdev->subsystem_vendor;
122 hbainfo.sub_system_id = dev->pdev->subsystem_device;
124 if (copy_to_user(arg, &hbainfo, sizeof(struct aac_hba_info))) { /* { dg-warning "potential exposure of sensitive information by copying uninitialized data from stack" "warning" } */
125 /* { dg-message "177 bytes are uninitialized" "how much" { target *-*-* } .-1 } */
126 /* [...snip...] */
129 return 0;
132 static int aac_get_hba_info_fixed(struct aac_dev *dev, void __user *arg)
134 struct aac_hba_info hbainfo;
136 memset(&hbainfo, 0, sizeof(hbainfo));
137 hbainfo.adapter_number = (u8) dev->id;
138 hbainfo.system_io_bus_number = dev->pdev->bus->number;
139 hbainfo.device_number = (dev->pdev->devfn >> 3);
140 hbainfo.function_number = (dev->pdev->devfn & 0x0007);
142 hbainfo.vendor_id = dev->pdev->vendor;
143 hbainfo.device_id = dev->pdev->device;
144 hbainfo.sub_vendor_id = dev->pdev->subsystem_vendor;
145 hbainfo.sub_system_id = dev->pdev->subsystem_device;
147 if (copy_to_user(arg, &hbainfo, sizeof(struct aac_hba_info))) { /* { dg-bogus "" } */
148 /* [...snip...] */
151 return 0;
154 /* An alternate fix using "= {0}" rather than memset. */
156 static int aac_get_hba_info_fixed_alt(struct aac_dev *dev, void __user *arg)
158 struct aac_hba_info hbainfo = {0};
160 memset(&hbainfo, 0, sizeof(hbainfo));
161 hbainfo.adapter_number = (u8) dev->id;
162 hbainfo.system_io_bus_number = dev->pdev->bus->number;
163 hbainfo.device_number = (dev->pdev->devfn >> 3);
164 hbainfo.function_number = (dev->pdev->devfn & 0x0007);
166 hbainfo.vendor_id = dev->pdev->vendor;
167 hbainfo.device_id = dev->pdev->device;
168 hbainfo.sub_vendor_id = dev->pdev->subsystem_vendor;
169 hbainfo.sub_system_id = dev->pdev->subsystem_device;
171 if (copy_to_user(arg, &hbainfo, sizeof(struct aac_hba_info))) { /* { dg-bogus "" } */
172 /* [...snip...] */
175 return 0;