Skip to content

Commit dca132a

Browse files
committed
Merge tag 'ras-urgent-2020-02-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull RAS fixes from Thomas Gleixner: "Two fixes for the AMD MCE driver: - Populate the per CPU MCA bank descriptor pointer only after it has been completely set up to prevent a use-after-free in case that one of the subsequent initialization step fails - Implement a proper release function for the sysfs entries of MCA threshold controls instead of freeing the memory right in the CPU teardown code, which leads to another use-after-free when the associated sysfs file is opened and accessed" * tag 'ras-urgent-2020-02-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/mce/amd: Fix kobject lifetime x86/mce/amd: Publish the bank pointer only after setup has succeeded
2 parents f3cc249 + 51dede9 commit dca132a

File tree

1 file changed

+27
-23
lines changed
  • arch/x86/kernel/cpu/mce

1 file changed

+27
-23
lines changed

arch/x86/kernel/cpu/mce/amd.c

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,9 +1163,12 @@ static const struct sysfs_ops threshold_ops = {
11631163
.store = store,
11641164
};
11651165

1166+
static void threshold_block_release(struct kobject *kobj);
1167+
11661168
static struct kobj_type threshold_ktype = {
11671169
.sysfs_ops = &threshold_ops,
11681170
.default_attrs = default_attrs,
1171+
.release = threshold_block_release,
11691172
};
11701173

11711174
static const char *get_name(unsigned int bank, struct threshold_block *b)
@@ -1198,8 +1201,9 @@ static const char *get_name(unsigned int bank, struct threshold_block *b)
11981201
return buf_mcatype;
11991202
}
12001203

1201-
static int allocate_threshold_blocks(unsigned int cpu, unsigned int bank,
1202-
unsigned int block, u32 address)
1204+
static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb,
1205+
unsigned int bank, unsigned int block,
1206+
u32 address)
12031207
{
12041208
struct threshold_block *b = NULL;
12051209
u32 low, high;
@@ -1243,24 +1247,20 @@ static int allocate_threshold_blocks(unsigned int cpu, unsigned int bank,
12431247

12441248
INIT_LIST_HEAD(&b->miscj);
12451249

1246-
if (per_cpu(threshold_banks, cpu)[bank]->blocks) {
1247-
list_add(&b->miscj,
1248-
&per_cpu(threshold_banks, cpu)[bank]->blocks->miscj);
1249-
} else {
1250-
per_cpu(threshold_banks, cpu)[bank]->blocks = b;
1251-
}
1250+
if (tb->blocks)
1251+
list_add(&b->miscj, &tb->blocks->miscj);
1252+
else
1253+
tb->blocks = b;
12521254

1253-
err = kobject_init_and_add(&b->kobj, &threshold_ktype,
1254-
per_cpu(threshold_banks, cpu)[bank]->kobj,
1255-
get_name(bank, b));
1255+
err = kobject_init_and_add(&b->kobj, &threshold_ktype, tb->kobj, get_name(bank, b));
12561256
if (err)
12571257
goto out_free;
12581258
recurse:
12591259
address = get_block_address(address, low, high, bank, ++block, cpu);
12601260
if (!address)
12611261
return 0;
12621262

1263-
err = allocate_threshold_blocks(cpu, bank, block, address);
1263+
err = allocate_threshold_blocks(cpu, tb, bank, block, address);
12641264
if (err)
12651265
goto out_free;
12661266

@@ -1345,8 +1345,6 @@ static int threshold_create_bank(unsigned int cpu, unsigned int bank)
13451345
goto out_free;
13461346
}
13471347

1348-
per_cpu(threshold_banks, cpu)[bank] = b;
1349-
13501348
if (is_shared_bank(bank)) {
13511349
refcount_set(&b->cpus, 1);
13521350

@@ -1357,9 +1355,13 @@ static int threshold_create_bank(unsigned int cpu, unsigned int bank)
13571355
}
13581356
}
13591357

1360-
err = allocate_threshold_blocks(cpu, bank, 0, msr_ops.misc(bank));
1361-
if (!err)
1362-
goto out;
1358+
err = allocate_threshold_blocks(cpu, b, bank, 0, msr_ops.misc(bank));
1359+
if (err)
1360+
goto out_free;
1361+
1362+
per_cpu(threshold_banks, cpu)[bank] = b;
1363+
1364+
return 0;
13631365

13641366
out_free:
13651367
kfree(b);
@@ -1368,8 +1370,12 @@ static int threshold_create_bank(unsigned int cpu, unsigned int bank)
13681370
return err;
13691371
}
13701372

1371-
static void deallocate_threshold_block(unsigned int cpu,
1372-
unsigned int bank)
1373+
static void threshold_block_release(struct kobject *kobj)
1374+
{
1375+
kfree(to_block(kobj));
1376+
}
1377+
1378+
static void deallocate_threshold_block(unsigned int cpu, unsigned int bank)
13731379
{
13741380
struct threshold_block *pos = NULL;
13751381
struct threshold_block *tmp = NULL;
@@ -1379,13 +1385,11 @@ static void deallocate_threshold_block(unsigned int cpu,
13791385
return;
13801386

13811387
list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) {
1382-
kobject_put(&pos->kobj);
13831388
list_del(&pos->miscj);
1384-
kfree(pos);
1389+
kobject_put(&pos->kobj);
13851390
}
13861391

1387-
kfree(per_cpu(threshold_banks, cpu)[bank]->blocks);
1388-
per_cpu(threshold_banks, cpu)[bank]->blocks = NULL;
1392+
kobject_put(&head->blocks->kobj);
13891393
}
13901394

13911395
static void __threshold_remove_blocks(struct threshold_bank *b)

0 commit comments

Comments
 (0)