Unverified Commit d3a550b8 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11215 Fix CVE-2024-40901

Merge Pull Request from: @ci-robot 
 
PR sync from: Wang Wensheng <wangwensheng4@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/QR4ARF2MTDP24XIPCMVDPJUZ62JVDOIJ/ 
Breno Leitao (1):
  scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory

Jia-Ju Bai (1):
  scsi: mpt3sas: Fix error return code of mpt3sas_base_attach()

Joe Perches (1):
  scsi: mpt3sas: Add ioc_<level> logging macros

Suganath Prabu (1):
  scsi: mpt3sas: Gracefully handle online firmware update


-- 
2.17.1
 
https://gitee.com/src-openeuler/kernel/issues/IACZL6 
 
Link:https://gitee.com/openeuler/kernel/pulls/11215

 

Reviewed-by: default avatarWeilong Chen <chenweilong@huawei.com>
Reviewed-by: default avatarLiu YongQiang <liuyongqiang13@huawei.com>
Signed-off-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
parents 60769662 bdacca4d
Loading
Loading
Loading
Loading
+118 −2
Original line number Diff line number Diff line
@@ -6608,6 +6608,12 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
	ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8);
	if (ioc->facts.MaxDevHandle % 8)
		ioc->pd_handles_sz++;
	/*
	 * pd_handles_sz should have, at least, the minimal room for
	 * set_bit()/test_bit(), otherwise out-of-memory touch may occur.
	 */
	ioc->pd_handles_sz = ALIGN(ioc->pd_handles_sz, sizeof(unsigned long));

	ioc->pd_handles = kzalloc(ioc->pd_handles_sz,
	    GFP_KERNEL);
	if (!ioc->pd_handles) {
@@ -6625,16 +6631,27 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
	ioc->pend_os_device_add_sz = (ioc->facts.MaxDevHandle / 8);
	if (ioc->facts.MaxDevHandle % 8)
		ioc->pend_os_device_add_sz++;

	/*
	 * pend_os_device_add_sz should have, at least, the minimal room for
	 * set_bit()/test_bit(), otherwise out-of-memory may occur.
	 */
	ioc->pend_os_device_add_sz = ALIGN(ioc->pend_os_device_add_sz,
					   sizeof(unsigned long));
	ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz,
	    GFP_KERNEL);
	if (!ioc->pend_os_device_add)
	if (!ioc->pend_os_device_add) {
		r = -ENOMEM;
		goto out_free_resources;
	}

	ioc->device_remove_in_progress_sz = ioc->pend_os_device_add_sz;
	ioc->device_remove_in_progress =
		kzalloc(ioc->device_remove_in_progress_sz, GFP_KERNEL);
	if (!ioc->device_remove_in_progress)
	if (!ioc->device_remove_in_progress) {
		r = -ENOMEM;
		goto out_free_resources;
	}

	ioc->fwfault_debug = mpt3sas_fwfault_debug;

@@ -6711,6 +6728,13 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
	if (r)
		goto out_free_resources;

	/*
	 * Copy current copy of IOCFacts in prev_fw_facts
	 * and it will be used during online firmware upgrade.
	 */
	memcpy(&ioc->prev_fw_facts, &ioc->facts,
	    sizeof(struct mpt3sas_facts));

	ioc->non_operational_loop = 0;
	ioc->got_task_abort_from_ioctl = 0;
	return 0;
@@ -6876,6 +6900,91 @@ mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc)
	wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 10 * HZ);
}

/**
 * _base_check_ioc_facts_changes - Look for increase/decrease of IOCFacts
 *     attributes during online firmware upgrade and update the corresponding
 *     IOC variables accordingly.
 *
 * @ioc: Pointer to MPT_ADAPTER structure
 */
static int
_base_check_ioc_facts_changes(struct MPT3SAS_ADAPTER *ioc)
{
	u16 pd_handles_sz;
	void *pd_handles = NULL, *blocking_handles = NULL;
	void *pend_os_device_add = NULL, *device_remove_in_progress = NULL;
	struct mpt3sas_facts *old_facts = &ioc->prev_fw_facts;

	if (ioc->facts.MaxDevHandle > old_facts->MaxDevHandle) {
		pd_handles_sz = (ioc->facts.MaxDevHandle / 8);
		if (ioc->facts.MaxDevHandle % 8)
			pd_handles_sz++;

		/*
		 * pd_handles should have, at least, the minimal room for
		 * set_bit()/test_bit(), otherwise out-of-memory touch may
		 * occur.
		 */
		pd_handles_sz = ALIGN(pd_handles_sz, sizeof(unsigned long));
		pd_handles = krealloc(ioc->pd_handles, pd_handles_sz,
		    GFP_KERNEL);
		if (!pd_handles) {
			ioc_info(ioc,
			    "Unable to allocate the memory for pd_handles of sz: %d\n",
			    pd_handles_sz);
			return -ENOMEM;
		}
		memset(pd_handles + ioc->pd_handles_sz, 0,
		    (pd_handles_sz - ioc->pd_handles_sz));
		ioc->pd_handles = pd_handles;

		blocking_handles = krealloc(ioc->blocking_handles,
		    pd_handles_sz, GFP_KERNEL);
		if (!blocking_handles) {
			ioc_info(ioc,
			    "Unable to allocate the memory for "
			    "blocking_handles of sz: %d\n",
			    pd_handles_sz);
			return -ENOMEM;
		}
		memset(blocking_handles + ioc->pd_handles_sz, 0,
		    (pd_handles_sz - ioc->pd_handles_sz));
		ioc->blocking_handles = blocking_handles;
		ioc->pd_handles_sz = pd_handles_sz;

		pend_os_device_add = krealloc(ioc->pend_os_device_add,
		    pd_handles_sz, GFP_KERNEL);
		if (!pend_os_device_add) {
			ioc_info(ioc,
			    "Unable to allocate the memory for pend_os_device_add of sz: %d\n",
			    pd_handles_sz);
			return -ENOMEM;
		}
		memset(pend_os_device_add + ioc->pend_os_device_add_sz, 0,
		    (pd_handles_sz - ioc->pend_os_device_add_sz));
		ioc->pend_os_device_add = pend_os_device_add;
		ioc->pend_os_device_add_sz = pd_handles_sz;

		device_remove_in_progress = krealloc(
		    ioc->device_remove_in_progress, pd_handles_sz, GFP_KERNEL);
		if (!device_remove_in_progress) {
			ioc_info(ioc,
			    "Unable to allocate the memory for "
			    "device_remove_in_progress of sz: %d\n "
			    , pd_handles_sz);
			return -ENOMEM;
		}
		memset(device_remove_in_progress +
		    ioc->device_remove_in_progress_sz, 0,
		    (pd_handles_sz - ioc->device_remove_in_progress_sz));
		ioc->device_remove_in_progress = device_remove_in_progress;
		ioc->device_remove_in_progress_sz = pd_handles_sz;
	}

	memcpy(&ioc->prev_fw_facts, &ioc->facts, sizeof(struct mpt3sas_facts));
	return 0;
}

/**
 * mpt3sas_base_hard_reset_handler - reset controller
 * @ioc: Pointer to MPT_ADAPTER structure
@@ -6941,6 +7050,13 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
	if (r)
		goto out;

	r = _base_check_ioc_facts_changes(ioc);
	if (r) {
		ioc_info(ioc,
		    "Some of the parameters got changed in this new firmware"
		    " image and it requires system reboot\n");
		goto out;
	}
	if (ioc->rdpq_array_enable && !ioc->rdpq_array_capable)
		panic("%s: Issue occurred with flashing controller firmware."
		      "Please reboot the system and ensure that the correct"
+11 −0
Original line number Diff line number Diff line
@@ -160,6 +160,15 @@ struct mpt3sas_nvme_cmd {
 */
#define MPT3SAS_FMT			"%s: "

#define ioc_err(ioc, fmt, ...)						\
	pr_err("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
#define ioc_notice(ioc, fmt, ...)					\
	pr_notice("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
#define ioc_warn(ioc, fmt, ...)						\
	pr_warn("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
#define ioc_info(ioc, fmt, ...)						\
	pr_info("%s: " fmt, (ioc)->name, ##__VA_ARGS__)

/*
 *  WarpDrive Specific Log codes
 */
@@ -1023,6 +1032,7 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
 * @event_log: event log pointer
 * @event_masks: events that are masked
 * @facts: static facts data
 * @prev_fw_facts: previous fw facts data
 * @pfacts: static port facts data
 * @manu_pg0: static manufacturing page 0
 * @manu_pg10: static manufacturing page 10
@@ -1226,6 +1236,7 @@ struct MPT3SAS_ADAPTER {

	/* static config pages */
	struct mpt3sas_facts facts;
	struct mpt3sas_facts prev_fw_facts;
	struct mpt3sas_port_facts *pfacts;
	Mpi2ManufacturingPage0_t manu_pg0;
	struct Mpi2ManufacturingPage10_t manu_pg10;