Commit dbb48097 authored by Zeng Heng's avatar Zeng Heng
Browse files

arm64/mpam: Fix out-of-bound access of cfg array

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAFGJ6



--------------------------------

The cfg array of per msc component is allocated according to the partid
number. The length of array should be (mpam_partid_max + 1) instead of
mpam_partid_max. Otherwise, when resctrl_arch_get_config() accesses
the array would raise slab-out-of-bounds fault like below:

BUG: KASAN: slab-out-of-bounds in resctrl_arch_get_config+0x404/0x7c8
Read of size 4 at addr ffff08280da29b64 by task mkdir/4156

Fixes: be74872a ("arm_mpam: Allow configuration to be applied and restored during cpu online")
Signed-off-by: default avatarZeng Heng <zengheng4@huawei.com>
parent bd0e745d
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -1247,7 +1247,7 @@ struct reprogram_ris {
/* Call with MSC lock held */
static int mpam_reprogram_ris(void *_arg)
{
	u16 partid, partid_max;
	u16 partid, num_partid;
	struct reprogram_ris *arg = _arg;
	struct mpam_msc_ris *ris = arg->ris;
	struct mpam_config *cfg = arg->cfg;
@@ -1256,9 +1256,9 @@ static int mpam_reprogram_ris(void *_arg)
		return 0;

	spin_lock(&partid_max_lock);
	partid_max = mpam_partid_max;
	num_partid = resctrl_arch_get_num_closid(NULL);
	spin_unlock(&partid_max_lock);
	for (partid = 0; partid < partid_max; partid++)
	for (partid = 0; partid < num_partid; partid++)
		mpam_reprogram_ris_partid(ris, partid, cfg);

	return 0;
@@ -1414,7 +1414,7 @@ static void mpam_reprogram_msc(struct mpam_msc *msc)
		}

		reset = true;
		for (partid = 0; partid < mpam_partid_max; partid++) {
		for (partid = 0; partid < resctrl_arch_get_num_closid(NULL); partid++) {
			cfg = &ris->comp->cfg[partid];
			if (cfg->features)
				reset = false;
@@ -2117,7 +2117,8 @@ static int __allocate_component_cfg(struct mpam_component *comp)
	if (comp->cfg)
		return 0;

	comp->cfg = kcalloc(mpam_partid_max, sizeof(*comp->cfg), GFP_KERNEL);
	comp->cfg = kcalloc(resctrl_arch_get_num_closid(NULL),
			    sizeof(*comp->cfg), GFP_KERNEL);
	if (!comp->cfg)
		return -ENOMEM;

@@ -2229,7 +2230,7 @@ void mpam_reset_class(struct mpam_class *class)

	idx = srcu_read_lock(&mpam_srcu);
	list_for_each_entry_rcu(comp, &class->components, class_list) {
		memset(comp->cfg, 0, (mpam_partid_max * sizeof(*comp->cfg)));
		memset(comp->cfg, 0, resctrl_arch_get_num_closid(NULL) * sizeof(*comp->cfg));

		list_for_each_entry_rcu(ris, &comp->ris, comp_list) {
			mutex_lock(&ris->msc->lock);