Skip to contentSkip to conversation

x86/mce/amd: Fix kobject lifetime

PATCH Applied Borislav Petkov 4 participants 8 messages Feb 14, 2020 – Feb 15, 2020

Subsystems (3)
lore
Share & tools
lore

Borislav Petkov

author maintainer
#0 lore raw

PATCH 1/1 x86/mce/amd: Fix kobject lifetime

From: Thomas Gleixner <[email protected]>

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 95268664390b ("[PATCH] x86_64: mce_amd support for family 0x10 processors")
---
 arch/x86/kernel/cpu/mce/amd.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)
arch/x86/kernel/cpu/mce/amd.c +11 -6
index e7313e5c497c..52de616a8065 100644
@@ -1163,9 +1163,12 @@ static const struct sysfs_ops threshold_ops = {
 	.store			= store,
 };
 
+static void threshold_block_release(struct kobject *kobj);
+
 static struct kobj_type threshold_ktype = {
 	.sysfs_ops		= &threshold_ops,
 	.default_attrs		= default_attrs,
+	.release		= threshold_block_release,
 };
 
 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)
 	return err;
 }
 
-static void deallocate_threshold_block(unsigned int cpu,
-						 unsigned int bank)
+static void threshold_block_release(struct kobject *kobj)
+{
+	kfree(to_block(kobj));
+}
+
+static void deallocate_threshold_block(unsigned int cpu, unsigned int bank)
 {
 	struct threshold_block *pos = NULL;
 	struct threshold_block *tmp = NULL;
@@ -1378,13 +1385,11 @@ static void deallocate_threshold_block(unsigned int cpu,
 		return;
 
 	list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) {
-		kobject_put(&pos->kobj);
 		list_del(&pos->miscj);
-		kfree(pos);
+		kobject_put(&pos->kobj);
 	}
 
-	kfree(per_cpu(threshold_banks, cpu)[bank]->blocks);
-	per_cpu(threshold_banks, cpu)[bank]->blocks = NULL;
+	kobject_put(&head->blocks->kobj);
 }
 
 static void __threshold_remove_blocks(struct threshold_bank *b)
Signature · 1 line
2.21.0
author maintainer
#1 lore raw
Quoted 21 lines · Borislav Petkov

From: Thomas Gleixner <[email protected]>

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.

Quoted 6 lines

[ bp: write commit message. ]

Fixes 95268664390b ("[PATCH] x86_64: mce_amd support for family 0x10 processors")

Damn git-send-email: it read out Cc: stable and added it to the Cc list. I've added

suppresscc = bodycc

to my .gitconfig.

Sorry stable guys.

Signature · 4 lines
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
maintainer
#2 lore raw
Quoted 29 lines · Borislav Petkov
Quoted 21 lines · Borislav Petkov

From: Thomas Gleixner <[email protected]>

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.

Quoted 6 lines

[ bp: write commit message. ]

Fixes 95268664390b ("[PATCH] x86_64: mce_amd support for family 0x10 processors")
Quoted 8 lines

Damn git-send-email: it read out Cc: stable and added it to the Cc list. I've added

suppresscc = bodycc

to my .gitconfig.

Sorry stable guys.

Does not bother me at all, it's fine to see stuff come by that will end up in future trees, it's not noise at all. So no need to suppress stable@vger if you don't want to.

thanks,

greg k-h

author maintainer
#3 lore raw
Quoted 3 lines · Greg KH

Does not bother me at all, it's fine to see stuff come by that will end up in future trees, it's not noise at all. So no need to suppress stable@vger if you don't want to.

Ok, but what about your formletter which you send to people explaining this is not how you should send a patch to stable?

Like this, for example:

https://lkml.kernel.org/r/[email protected]

Signature · 4 lines
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
#4 lore raw
Quoted 11 lines · Borislav Petkov
Quoted 3 lines · Greg KH

Does not bother me at all, it's fine to see stuff come by that will end up in future trees, it's not noise at all. So no need to suppress stable@vger if you don't want to.

Ok, but what about your formletter which you send to people explaining this is not how you should send a patch to stable?

Like this, for example:

https://lkml.kernel.org/r/[email protected]

This once Cc'ed stable but lacked a Cc: stable tag in the changelog.

Thanks,

tglx

author maintainer
#5 lore raw
Quoted 1 line · Thomas Gleixner

This once Cc'ed stable but lacked a Cc: stable tag in the changelog.

So that's the difference. Ok, I'm fine with that.

/me removes "suppresscc = bodycc" from his .gitconfig again.

Thx.

Signature · 4 lines
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
maintainer
#6 lore raw
In reply to Thomas Gleixner
Quoted 7 lines · Thomas Gleixner
Quoted 5 lines · Borislav Petkov
Quoted 3 lines · Greg KH

Does not bother me at all, it's fine to see stuff come by that will end up in future trees, it's not noise at all. So no need to suppress stable@vger if you don't want to.

Quoted 8 lines
Quoted 6 lines

Ok, but what about your formletter which you send to people explaining this is not how you should send a patch to stable?

Like this, for example:

https://lkml.kernel.org/r/[email protected]

This once Cc'ed stable but lacked a Cc: stable tag in the changelog.

Exactly :)

#7 lore raw
In reply to Borislav Petkov
The following commit has been merged into the ras/urgent branch of tip:

The following commit has been merged into the ras/urgent branch of tip:

Commit-ID:     51dede9c05df2b78acd6dcf6a17d21f0877d2d7b
Gitweb:        https://git.kernel.org/tip/51dede9c05df2b78acd6dcf6a17d21f0877d2d7b
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Thu, 13 Feb 2020 19:01:34 +01:00
Committer:     Borislav Petkov <[email protected]>
CommitterDate: Fri, 14 Feb 2020 09:28:31 +01:00

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 95268664390b ("[PATCH] x86_64: mce_amd support for family 0x10 processors")
---
 arch/x86/kernel/cpu/mce/amd.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)
arch/x86/kernel/cpu/mce/amd.c +11 -6
index e7313e5..52de616 100644
@@ -1163,9 +1163,12 @@ static const struct sysfs_ops threshold_ops = {
 	.store			= store,
 };
 
+static void threshold_block_release(struct kobject *kobj);
+
 static struct kobj_type threshold_ktype = {
 	.sysfs_ops		= &threshold_ops,
 	.default_attrs		= default_attrs,
+	.release		= threshold_block_release,
 };
 
 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)
 	return err;
 }
 
-static void deallocate_threshold_block(unsigned int cpu,
-						 unsigned int bank)
+static void threshold_block_release(struct kobject *kobj)
+{
+	kfree(to_block(kobj));
+}
+
+static void deallocate_threshold_block(unsigned int cpu, unsigned int bank)
 {
 	struct threshold_block *pos = NULL;
 	struct threshold_block *tmp = NULL;
@@ -1378,13 +1385,11 @@ static void deallocate_threshold_block(unsigned int cpu,
 		return;
 
 	list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) {
-		kobject_put(&pos->kobj);
 		list_del(&pos->miscj);
-		kfree(pos);
+		kobject_put(&pos->kobj);
 	}
 
-	kfree(per_cpu(threshold_banks, cpu)[bank]->blocks);
-	per_cpu(threshold_banks, cpu)[bank]->blocks = NULL;
+	kobject_put(&head->blocks->kobj);
 }
 
 static void __threshold_remove_blocks(struct threshold_bank *b)