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: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2020-10-15 09:54:45 -07:00
commit 0c124aa5c4
2 changed files with 8 additions and 10 deletions

View File

@ -1597,7 +1597,7 @@ static int smcr_buf_map_usable_links(struct smc_link_group *lgr,
return rc; 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, static struct smc_buf_desc *smcd_new_buf_create(struct smc_link_group *lgr,
bool is_dmb, int bufsize) 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); rc = smc_ism_register_dmb(lgr, bufsize, buf_desc);
if (rc) { if (rc) {
kfree(buf_desc); 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); buf_desc->pages = virt_to_page(buf_desc->cpu_addr);
/* CDC header stored in buf. So, pretend it was smaller */ /* CDC header stored in buf. So, pretend it was smaller */

View File

@ -233,8 +233,6 @@ static bool smc_llc_flow_start(struct smc_llc_flow *flow,
default: default:
flow->type = SMC_LLC_FLOW_NONE; flow->type = SMC_LLC_FLOW_NONE;
} }
if (qentry == lgr->delayed_event)
lgr->delayed_event = NULL;
smc_llc_flow_qentry_set(flow, qentry); smc_llc_flow_qentry_set(flow, qentry);
spin_unlock_bh(&lgr->llc_flow_lock); spin_unlock_bh(&lgr->llc_flow_lock);
return true; return true;
@ -1603,13 +1601,12 @@ static void smc_llc_event_work(struct work_struct *work)
struct smc_llc_qentry *qentry; struct smc_llc_qentry *qentry;
if (!lgr->llc_flow_lcl.type && lgr->delayed_event) { if (!lgr->llc_flow_lcl.type && lgr->delayed_event) {
if (smc_link_usable(lgr->delayed_event->link)) { qentry = lgr->delayed_event;
smc_llc_event_handler(lgr->delayed_event); lgr->delayed_event = NULL;
} else { if (smc_link_usable(qentry->link))
qentry = lgr->delayed_event; smc_llc_event_handler(qentry);
lgr->delayed_event = NULL; else
kfree(qentry); kfree(qentry);
}
} }
again: again: