Skip to content

Commit 9d69b4a

Browse files
KAGA-KOKOgregkh
authored andcommitted
x86/mce/amd: Fix kobject lifetime
commit 51dede9 upstream. 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 <tglx@linutronix.de> Signed-off-by: Borislav Petkov <bp@suse.de> Cc: <stable@vger.kernel.org> Link: https://lkml.kernel.org/r/20200214082801.13836-1-bp@alien8.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 10be332 commit 9d69b4a

1 file changed

Lines changed: 11 additions & 6 deletions

File tree

arch/x86/kernel/cpu/mcheck/mce_amd.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -846,9 +846,12 @@ static const struct sysfs_ops threshold_ops = {
846846
.store = store,
847847
};
848848

849+
static void threshold_block_release(struct kobject *kobj);
850+
849851
static struct kobj_type threshold_ktype = {
850852
.sysfs_ops = &threshold_ops,
851853
.default_attrs = default_attrs,
854+
.release = threshold_block_release,
852855
};
853856

854857
static const char *get_name(unsigned int bank, struct threshold_block *b)
@@ -1073,8 +1076,12 @@ static int threshold_create_device(unsigned int cpu)
10731076
return err;
10741077
}
10751078

1076-
static void deallocate_threshold_block(unsigned int cpu,
1077-
unsigned int bank)
1079+
static void threshold_block_release(struct kobject *kobj)
1080+
{
1081+
kfree(to_block(kobj));
1082+
}
1083+
1084+
static void deallocate_threshold_block(unsigned int cpu, unsigned int bank)
10781085
{
10791086
struct threshold_block *pos = NULL;
10801087
struct threshold_block *tmp = NULL;
@@ -1084,13 +1091,11 @@ static void deallocate_threshold_block(unsigned int cpu,
10841091
return;
10851092

10861093
list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) {
1087-
kobject_put(&pos->kobj);
10881094
list_del(&pos->miscj);
1089-
kfree(pos);
1095+
kobject_put(&pos->kobj);
10901096
}
10911097

1092-
kfree(per_cpu(threshold_banks, cpu)[bank]->blocks);
1093-
per_cpu(threshold_banks, cpu)[bank]->blocks = NULL;
1098+
kobject_put(&head->blocks->kobj);
10941099
}
10951100

10961101
static void __threshold_remove_blocks(struct threshold_bank *b)

0 commit comments

Comments
 (0)