diff options
| -rw-r--r-- | drivers/firmware/dmi_scan.c | 23 |
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, | |||
| 191 | static void __init dmi_save_uuid(const struct dmi_header *dm, int slot, | 191 | static 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, | |||
| 228 | static void __init dmi_save_type(const struct dmi_header *dm, int slot, | 229 | static 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 | ||
| 279 | static void __init dmi_save_oem_strings_devices(const struct dmi_header *dm) | 281 | static 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"); |
