Commit 0c124aa5 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-smc-fixes-2020-10-14'

Karsten Graul says:

====================
net/smc: fixes 2020-10-14

The first patch fixes a possible use-after-free of delayed llc events.
Patch 2 corrects the number of DMB buffer sizes. And patch 3 ensures
a correctly formatted return code when smc_ism_register_dmb() fails to
create a new DMB.
====================

Link: https://lore.kernel.org/r/20201014174329.35791-1-kgraul@linux.ibm.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1d273fcc 6b1bbf94
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -1597,7 +1597,7 @@ out:
	return rc;
}

#define SMCD_DMBE_SIZES		7 /* 0 -> 16KB, 1 -> 32KB, .. 6 -> 1MB */
#define SMCD_DMBE_SIZES		6 /* 0 -> 16KB, 1 -> 32KB, .. 6 -> 1MB */

static struct smc_buf_desc *smcd_new_buf_create(struct smc_link_group *lgr,
						bool is_dmb, int bufsize)
@@ -1616,7 +1616,8 @@ static struct smc_buf_desc *smcd_new_buf_create(struct smc_link_group *lgr,
		rc = smc_ism_register_dmb(lgr, bufsize, buf_desc);
		if (rc) {
			kfree(buf_desc);
			return (rc == -ENOMEM) ? ERR_PTR(-EAGAIN) : ERR_PTR(rc);
			return (rc == -ENOMEM) ? ERR_PTR(-EAGAIN) :
						 ERR_PTR(-EIO);
		}
		buf_desc->pages = virt_to_page(buf_desc->cpu_addr);
		/* CDC header stored in buf. So, pretend it was smaller */
+5 −8
Original line number Diff line number Diff line
@@ -233,8 +233,6 @@ static bool smc_llc_flow_start(struct smc_llc_flow *flow,
	default:
		flow->type = SMC_LLC_FLOW_NONE;
	}
	if (qentry == lgr->delayed_event)
		lgr->delayed_event = NULL;
	smc_llc_flow_qentry_set(flow, qentry);
	spin_unlock_bh(&lgr->llc_flow_lock);
	return true;
@@ -1603,14 +1601,13 @@ static void smc_llc_event_work(struct work_struct *work)
	struct smc_llc_qentry *qentry;

	if (!lgr->llc_flow_lcl.type && lgr->delayed_event) {
		if (smc_link_usable(lgr->delayed_event->link)) {
			smc_llc_event_handler(lgr->delayed_event);
		} else {
		qentry = lgr->delayed_event;
		lgr->delayed_event = NULL;
		if (smc_link_usable(qentry->link))
			smc_llc_event_handler(qentry);
		else
			kfree(qentry);
	}
	}

again:
	spin_lock_bh(&lgr->llc_event_q_lock);