mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-18 20:16:16 +07:00
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. -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAl5RkwATHHRnbHhAbGlu dXRyb25peC5kZQAKCRCmGPVMDXSYoY6ED/4oafN9DmeY18oUv1QpoMQQMa6iduz6 udemhpjqVXO7R1Ste4ccM/fIQ8sMjf58isuxUClcDwrX3fxv+lusK2iVPEw99Vpo w1xSjdXNW0KSSiQko9oMHVu+xcXIt8vxpL4YyjEuR81rcoecFaq2c2KhLMAW4o0p 3mEv7/QYPfpKc4ydcbcHo2JF6U1sfUpsWpoe/SxpXRpxeoy64baCWZGbcsUXqjB6 3MRxxy+ypKKKPPUM1py4D/ViDXwkhhP+gMD4ljWXCprpul/KuXAMEgvW39MtVsBJ uMF3PMXqjKx+WY492tpxtdZjWej+X13ID/cTc2w1EBHz30Qxmc6RieTKi6FzsJYB PKsTWdGarzORioaBg51Riq27C3+fjHbe6WqkhIQzmenSIwiV1o6o4IyuOs5sdlxX rjIk/ssNeAxRpCy308i6Vaq98PBZqAY1/iUZN50vAzldH3bwKxobowjn+AYStA0c 9BF5zw7/3oXB4WaByuBwJ3DzWjqiXM4EUPu7LYF9DVSvj+A2xOmhwN+uz3SK6hBk vkxiFE50Lo2qoDaATJozY8+nxgUKRNiDdz+udhVsoQxNKWUMxirsH18TFu8yBl2r HGKsfCBY4CnV64WRy5IKQsqt3EhAgAUUoD0jSy7P3xf4HwSKAn/9OZ1cWQAo1wzQ xnXUtRDFc7ScHg== =2f84 -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
dca132a60f
@ -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)
|
||||
@ -1198,8 +1201,9 @@ static const char *get_name(unsigned int bank, struct threshold_block *b)
|
||||
return buf_mcatype;
|
||||
}
|
||||
|
||||
static int allocate_threshold_blocks(unsigned int cpu, unsigned int bank,
|
||||
unsigned int block, u32 address)
|
||||
static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb,
|
||||
unsigned int bank, unsigned int block,
|
||||
u32 address)
|
||||
{
|
||||
struct threshold_block *b = NULL;
|
||||
u32 low, high;
|
||||
@ -1243,16 +1247,12 @@ static int allocate_threshold_blocks(unsigned int cpu, unsigned int bank,
|
||||
|
||||
INIT_LIST_HEAD(&b->miscj);
|
||||
|
||||
if (per_cpu(threshold_banks, cpu)[bank]->blocks) {
|
||||
list_add(&b->miscj,
|
||||
&per_cpu(threshold_banks, cpu)[bank]->blocks->miscj);
|
||||
} else {
|
||||
per_cpu(threshold_banks, cpu)[bank]->blocks = b;
|
||||
}
|
||||
if (tb->blocks)
|
||||
list_add(&b->miscj, &tb->blocks->miscj);
|
||||
else
|
||||
tb->blocks = b;
|
||||
|
||||
err = kobject_init_and_add(&b->kobj, &threshold_ktype,
|
||||
per_cpu(threshold_banks, cpu)[bank]->kobj,
|
||||
get_name(bank, b));
|
||||
err = kobject_init_and_add(&b->kobj, &threshold_ktype, tb->kobj, get_name(bank, b));
|
||||
if (err)
|
||||
goto out_free;
|
||||
recurse:
|
||||
@ -1260,7 +1260,7 @@ static int allocate_threshold_blocks(unsigned int cpu, unsigned int bank,
|
||||
if (!address)
|
||||
return 0;
|
||||
|
||||
err = allocate_threshold_blocks(cpu, bank, block, address);
|
||||
err = allocate_threshold_blocks(cpu, tb, bank, block, address);
|
||||
if (err)
|
||||
goto out_free;
|
||||
|
||||
@ -1345,8 +1345,6 @@ static int threshold_create_bank(unsigned int cpu, unsigned int bank)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
per_cpu(threshold_banks, cpu)[bank] = b;
|
||||
|
||||
if (is_shared_bank(bank)) {
|
||||
refcount_set(&b->cpus, 1);
|
||||
|
||||
@ -1357,9 +1355,13 @@ static int threshold_create_bank(unsigned int cpu, unsigned int bank)
|
||||
}
|
||||
}
|
||||
|
||||
err = allocate_threshold_blocks(cpu, bank, 0, msr_ops.misc(bank));
|
||||
if (!err)
|
||||
goto out;
|
||||
err = allocate_threshold_blocks(cpu, b, bank, 0, msr_ops.misc(bank));
|
||||
if (err)
|
||||
goto out_free;
|
||||
|
||||
per_cpu(threshold_banks, cpu)[bank] = b;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
kfree(b);
|
||||
@ -1368,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;
|
||||
@ -1379,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)
|
||||
|
Loading…
Reference in New Issue
Block a user