Skip to content

Commit 51dede9

Browse files
KAGA-KOKOsuryasaimadhu
authored andcommitted
x86/mce/amd: Fix kobject lifetime
Accessing the MCA thresholding controls in sysfs concurrently with CPU hotplug can lead to a couple of KASAN-reported issues: BUG: KASAN: use-after-free in sysfs_file_ops+0x155/0x180 Read of size 8 at addr ffff888367578940 by task grep/4019 and BUG: KASAN: use-after-free in show_error_count+0x15c/0x180 Read of size 2 at addr ffff888368a05514 by task grep/4454 for example. Both result from the fact that the threshold block creation/teardown code frees the descriptor memory itself instead of defining proper ->release function and leaving it to the driver core to take care of that, after all sysfs accesses have completed. Do that and get rid of the custom freeing code, fixing the above UAFs in the process. [ bp: write commit message. ] Fixes: 9526866 ("[PATCH] x86_64: mce_amd support for family 0x10 processors") Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Cc: <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 6e5cf31 commit 51dede9

File tree

1 file changed

+11
-6
lines changed
  • arch/x86/kernel/cpu/mce

1 file changed

+11
-6
lines changed

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

Lines changed: 11 additions & 6 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)
@@ -1367,8 +1370,12 @@ static int threshold_create_bank(unsigned int cpu, unsigned int bank)
13671370
return err;
13681371
}
13691372

1370-
static void deallocate_threshold_block(unsigned int cpu,
1371-
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)
13721379
{
13731380
struct threshold_block *pos = NULL;
13741381
struct threshold_block *tmp = NULL;
@@ -1378,13 +1385,11 @@ static void deallocate_threshold_block(unsigned int cpu,
13781385
return;
13791386

13801387
list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) {
1381-
kobject_put(&pos->kobj);
13821388
list_del(&pos->miscj);
1383-
kfree(pos);
1389+
kobject_put(&pos->kobj);
13841390
}
13851391

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

13901395
static void __threshold_remove_blocks(struct threshold_bank *b)

0 commit comments

Comments
 (0)