Skip to content

Commit 826c416

Browse files
Linda Knippersdjbw
authored andcommitted
nfit: Account for table size length variation
The size of NFIT tables don't necessarily match the size of the data structures that we use for them. For example, the NVDIMM Control Region Structure table is shorter for a device with no block control windows than for a device with block control windows. Other tables, such as Flush Hint Address Structure and the Interleave Structure are variable length by definition. Account for the size difference when comparing table entries by using the actual table size from the table header if it's less than the structure size. Signed-off-by: Linda Knippers <linda.knippers@hpe.com> Acked-by: Vishal Verma <vishal.l.verma@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent bc0d0d0 commit 826c416

1 file changed

Lines changed: 12 additions & 6 deletions

File tree

drivers/acpi/nfit.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,12 @@ static bool add_spa(struct acpi_nfit_desc *acpi_desc,
233233
struct nfit_table_prev *prev,
234234
struct acpi_nfit_system_address *spa)
235235
{
236+
size_t length = min_t(size_t, sizeof(*spa), spa->header.length);
236237
struct device *dev = acpi_desc->dev;
237238
struct nfit_spa *nfit_spa;
238239

239240
list_for_each_entry(nfit_spa, &prev->spas, list) {
240-
if (memcmp(nfit_spa->spa, spa, sizeof(*spa)) == 0) {
241+
if (memcmp(nfit_spa->spa, spa, length) == 0) {
241242
list_move_tail(&nfit_spa->list, &acpi_desc->spas);
242243
return true;
243244
}
@@ -259,11 +260,12 @@ static bool add_memdev(struct acpi_nfit_desc *acpi_desc,
259260
struct nfit_table_prev *prev,
260261
struct acpi_nfit_memory_map *memdev)
261262
{
263+
size_t length = min_t(size_t, sizeof(*memdev), memdev->header.length);
262264
struct device *dev = acpi_desc->dev;
263265
struct nfit_memdev *nfit_memdev;
264266

265267
list_for_each_entry(nfit_memdev, &prev->memdevs, list)
266-
if (memcmp(nfit_memdev->memdev, memdev, sizeof(*memdev)) == 0) {
268+
if (memcmp(nfit_memdev->memdev, memdev, length) == 0) {
267269
list_move_tail(&nfit_memdev->list, &acpi_desc->memdevs);
268270
return true;
269271
}
@@ -284,11 +286,12 @@ static bool add_dcr(struct acpi_nfit_desc *acpi_desc,
284286
struct nfit_table_prev *prev,
285287
struct acpi_nfit_control_region *dcr)
286288
{
289+
size_t length = min_t(size_t, sizeof(*dcr), dcr->header.length);
287290
struct device *dev = acpi_desc->dev;
288291
struct nfit_dcr *nfit_dcr;
289292

290293
list_for_each_entry(nfit_dcr, &prev->dcrs, list)
291-
if (memcmp(nfit_dcr->dcr, dcr, sizeof(*dcr)) == 0) {
294+
if (memcmp(nfit_dcr->dcr, dcr, length) == 0) {
292295
list_move_tail(&nfit_dcr->list, &acpi_desc->dcrs);
293296
return true;
294297
}
@@ -308,11 +311,12 @@ static bool add_bdw(struct acpi_nfit_desc *acpi_desc,
308311
struct nfit_table_prev *prev,
309312
struct acpi_nfit_data_region *bdw)
310313
{
314+
size_t length = min_t(size_t, sizeof(*bdw), bdw->header.length);
311315
struct device *dev = acpi_desc->dev;
312316
struct nfit_bdw *nfit_bdw;
313317

314318
list_for_each_entry(nfit_bdw, &prev->bdws, list)
315-
if (memcmp(nfit_bdw->bdw, bdw, sizeof(*bdw)) == 0) {
319+
if (memcmp(nfit_bdw->bdw, bdw, length) == 0) {
316320
list_move_tail(&nfit_bdw->list, &acpi_desc->bdws);
317321
return true;
318322
}
@@ -332,11 +336,12 @@ static bool add_idt(struct acpi_nfit_desc *acpi_desc,
332336
struct nfit_table_prev *prev,
333337
struct acpi_nfit_interleave *idt)
334338
{
339+
size_t length = min_t(size_t, sizeof(*idt), idt->header.length);
335340
struct device *dev = acpi_desc->dev;
336341
struct nfit_idt *nfit_idt;
337342

338343
list_for_each_entry(nfit_idt, &prev->idts, list)
339-
if (memcmp(nfit_idt->idt, idt, sizeof(*idt)) == 0) {
344+
if (memcmp(nfit_idt->idt, idt, length) == 0) {
340345
list_move_tail(&nfit_idt->list, &acpi_desc->idts);
341346
return true;
342347
}
@@ -356,11 +361,12 @@ static bool add_flush(struct acpi_nfit_desc *acpi_desc,
356361
struct nfit_table_prev *prev,
357362
struct acpi_nfit_flush_address *flush)
358363
{
364+
size_t length = min_t(size_t, sizeof(*flush), flush->header.length);
359365
struct device *dev = acpi_desc->dev;
360366
struct nfit_flush *nfit_flush;
361367

362368
list_for_each_entry(nfit_flush, &prev->flushes, list)
363-
if (memcmp(nfit_flush->flush, flush, sizeof(*flush)) == 0) {
369+
if (memcmp(nfit_flush->flush, flush, length) == 0) {
364370
list_move_tail(&nfit_flush->list, &acpi_desc->flushes);
365371
return true;
366372
}

0 commit comments

Comments
 (0)