aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firmware/dmi_scan.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index fc30249132f5..783041964439 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -178,7 +178,7 @@ static void __init dmi_save_ident(const struct dmi_header *dm, int slot,
178 const char *d = (const char *) dm; 178 const char *d = (const char *) dm;
179 const char *p; 179 const char *p;
180 180
181 if (dmi_ident[slot]) 181 if (dmi_ident[slot] || dm->length <= string)
182 return; 182 return;
183 183
184 p = dmi_string(dm, d[string]); 184 p = dmi_string(dm, d[string]);
@@ -191,13 +191,14 @@ static void __init dmi_save_ident(const struct dmi_header *dm, int slot,
191static void __init dmi_save_uuid(const struct dmi_header *dm, int slot, 191static void __init dmi_save_uuid(const struct dmi_header *dm, int slot,
192 int index) 192 int index)
193{ 193{
194 const u8 *d = (u8 *) dm + index; 194 const u8 *d;
195 char *s; 195 char *s;
196 int is_ff = 1, is_00 = 1, i; 196 int is_ff = 1, is_00 = 1, i;
197 197
198 if (dmi_ident[slot]) 198 if (dmi_ident[slot] || dm->length <= index + 16)
199 return; 199 return;
200 200
201 d = (u8 *) dm + index;
201 for (i = 0; i < 16 && (is_ff || is_00); i++) { 202 for (i = 0; i < 16 && (is_ff || is_00); i++) {
202 if (d[i] != 0x00) 203 if (d[i] != 0x00)
203 is_00 = 0; 204 is_00 = 0;
@@ -228,16 +229,17 @@ static void __init dmi_save_uuid(const struct dmi_header *dm, int slot,
228static void __init dmi_save_type(const struct dmi_header *dm, int slot, 229static void __init dmi_save_type(const struct dmi_header *dm, int slot,
229 int index) 230 int index)
230{ 231{
231 const u8 *d = (u8 *) dm + index; 232 const u8 *d;
232 char *s; 233 char *s;
233 234
234 if (dmi_ident[slot]) 235 if (dmi_ident[slot] || dm->length <= index)
235 return; 236 return;
236 237
237 s = dmi_alloc(4); 238 s = dmi_alloc(4);
238 if (!s) 239 if (!s)
239 return; 240 return;
240 241
242 d = (u8 *) dm + index;
241 sprintf(s, "%u", *d & 0x7F); 243 sprintf(s, "%u", *d & 0x7F);
242 dmi_ident[slot] = s; 244 dmi_ident[slot] = s;
243} 245}
@@ -278,9 +280,13 @@ static void __init dmi_save_devices(const struct dmi_header *dm)
278 280
279static void __init dmi_save_oem_strings_devices(const struct dmi_header *dm) 281static void __init dmi_save_oem_strings_devices(const struct dmi_header *dm)
280{ 282{
281 int i, count = *(u8 *)(dm + 1); 283 int i, count;
282 struct dmi_device *dev; 284 struct dmi_device *dev;
283 285
286 if (dm->length < 0x05)
287 return;
288
289 count = *(u8 *)(dm + 1);
284 for (i = 1; i <= count; i++) { 290 for (i = 1; i <= count; i++) {
285 const char *devname = dmi_string(dm, i); 291 const char *devname = dmi_string(dm, i);
286 292
@@ -353,6 +359,9 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm)
353 const char *name; 359 const char *name;
354 const u8 *d = (u8 *)dm; 360 const u8 *d = (u8 *)dm;
355 361
362 if (dm->length < 0x0B)
363 return;
364
356 /* Skip disabled device */ 365 /* Skip disabled device */
357 if ((d[0x5] & 0x80) == 0) 366 if ((d[0x5] & 0x80) == 0)
358 return; 367 return;
@@ -387,7 +396,7 @@ static void __init save_mem_devices(const struct dmi_header *dm, void *v)
387 const char *d = (const char *)dm; 396 const char *d = (const char *)dm;
388 static int nr; 397 static int nr;
389 398
390 if (dm->type != DMI_ENTRY_MEM_DEVICE) 399 if (dm->type != DMI_ENTRY_MEM_DEVICE || dm->length < 0x12)
391 return; 400 return;
392 if (nr >= dmi_memdev_nr) { 401 if (nr >= dmi_memdev_nr) {
393 pr_warn(FW_BUG "Too many DIMM entries in SMBIOS table\n"); 402 pr_warn(FW_BUG "Too many DIMM entries in SMBIOS table\n");