<div dir="ltr"><div>While testing the old code, IBM identified the issue and came up with that patch, that they are now bringing upstream.<br>The patch was already tested by IBM, but</div>I provided a patched kernel based on Ubuntu (focal) master-next on top for further testing:<div><a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1882088/comments/12">https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1882088/comments/12</a></div><div>and I'm expecting some feedback from the initial reporter (IBM) on that, too.</div><div><br></div><div>Thx, Frank<br><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jul 13, 2020 at 9:20 AM Stefan Bader <<a href="mailto:stefan.bader@canonical.com">stefan.bader@canonical.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 10.07.20 21:21, <a href="mailto:frank.heimes@canonical.com" target="_blank">frank.heimes@canonical.com</a> wrote:<br>
> From: Ursula Braun <<a href="mailto:ubraun@linux.ibm.com" target="_blank">ubraun@linux.ibm.com</a>><br>
> <br>
> BugLink: <a href="https://bugs.launchpad.net/bugs/1882088" rel="noreferrer" target="_blank">https://bugs.launchpad.net/bugs/1882088</a><br>
> <br>
> CLC proposal messages of future SMCD versions could be larger than SMCD<br>
> V1 CLC proposal messages.<br>
> To enable toleration in SMC V1 the receival of CLC proposal messages<br>
> is adapted:<br>
> * accept larger length values in CLC proposal<br>
> * check trailing eye catcher for incoming CLC proposal with V1 length only<br>
> * receive the whole CLC proposal even in cases it does not fit into the<br>
> V1 buffer<br>
> <br>
> Fixes: e7b7a64a8493d ("smc: support variable CLC proposal messages")<br>
> Signed-off-by: Ursula Braun <<a href="mailto:ubraun@linux.ibm.com" target="_blank">ubraun@linux.ibm.com</a>><br>
> Signed-off-by: Karsten Graul <<a href="mailto:kgraul@linux.ibm.com" target="_blank">kgraul@linux.ibm.com</a>><br>
> Signed-off-by: David S. Miller <<a href="mailto:davem@davemloft.net" target="_blank">davem@davemloft.net</a>><br>
> (cherry picked from commit fb4f79264c0fc6fd5a68ffe3e31bfff97311e1f1i linux-next)<br>
> Signed-off-by: Frank Heimes <<a href="mailto:frank.heimes@canonical.com" target="_blank">frank.heimes@canonical.com</a>><br>
Acked-by: Stefan Bader <<a href="mailto:stefan.bader@canonical.com" target="_blank">stefan.bader@canonical.com</a>><br>
> ---<br>
<br>
I am a bit torn here. Though not extremely large, I find it hard to decide about<br>
risk based on the delta. And it is common code that is changed. On the positive<br>
side it is queued upstream, but that not necessarily means it is without flaws.<br>
Have been (or will there be) tests of the new code using the old version (if<br>
that is possible), old and new, and both new?<br>
<br>
-Stefan<br>
<br>
> net/smc/smc_clc.c | 45 ++++++++++++++++++++++++w ++++++++-------------<br>
> net/smc/smc_clc.h | 4 ++++<br>
> 2 files changed, 36 insertions(+), 13 deletions(-)<br>
> <br>
> diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c<br>
> index aee9ccfa99c2..640cce262015 100644<br>
> --- a/net/smc/smc_clc.c<br>
> +++ b/net/smc/smc_clc.c<br>
> @@ -27,6 +27,7 @@<br>
> <br>
> #define SMCR_CLC_ACCEPT_CONFIRM_LEN 68<br>
> #define SMCD_CLC_ACCEPT_CONFIRM_LEN 48<br>
> +#define SMC_CLC_RECV_BUF_LEN 100<br>
> <br>
> /* eye catcher "SMCR" EBCDIC for CLC messages */<br>
> static const char SMC_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xd9'};<br>
> @@ -36,7 +37,7 @@ static const char SMCD_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xc4'};<br>
> /* check if received message has a correct header length and contains valid<br>
> * heading and trailing eyecatchers<br>
> */<br>
> -static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm)<br>
> +static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm, bool check_trl)<br>
> {<br>
> struct smc_clc_msg_proposal_prefix *pclc_prfx;<br>
> struct smc_clc_msg_accept_confirm *clc;<br>
> @@ -49,12 +50,9 @@ static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm)<br>
> return false;<br>
> switch (clcm->type) {<br>
> case SMC_CLC_PROPOSAL:<br>
> - if (clcm->path != SMC_TYPE_R && clcm->path != SMC_TYPE_D &&<br>
> - clcm->path != SMC_TYPE_B)<br>
> - return false;<br>
> pclc = (struct smc_clc_msg_proposal *)clcm;<br>
> pclc_prfx = smc_clc_proposal_get_prefix(pclc);<br>
> - if (ntohs(pclc->hdr.length) !=<br>
> + if (ntohs(pclc->hdr.length) <<br>
> sizeof(*pclc) + ntohs(pclc->iparea_offset) +<br>
> sizeof(*pclc_prfx) +<br>
> pclc_prfx->ipv6_prefixes_cnt *<br>
> @@ -86,7 +84,8 @@ static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm)<br>
> default:<br>
> return false;<br>
> }<br>
> - if (memcmp(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&<br>
> + if (check_trl &&<br>
> + memcmp(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&<br>
> memcmp(trl->eyecatcher, SMCD_EYECATCHER, sizeof(SMCD_EYECATCHER)))<br>
> return false;<br>
> return true;<br>
> @@ -276,7 +275,8 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,<br>
> struct msghdr msg = {NULL, 0};<br>
> int reason_code = 0;<br>
> struct kvec vec = {buf, buflen};<br>
> - int len, datlen;<br>
> + int len, datlen, recvlen;<br>
> + bool check_trl = true;<br>
> int krflags;<br>
> <br>
> /* peek the first few bytes to determine length of data to receive<br>
> @@ -320,10 +320,7 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,<br>
> }<br>
> datlen = ntohs(clcm->length);<br>
> if ((len < sizeof(struct smc_clc_msg_hdr)) ||<br>
> - (datlen > buflen) ||<br>
> - (clcm->version != SMC_CLC_V1) ||<br>
> - (clcm->path != SMC_TYPE_R && clcm->path != SMC_TYPE_D &&<br>
> - clcm->path != SMC_TYPE_B) ||<br>
> + (clcm->version < SMC_CLC_V1) ||<br>
> ((clcm->type != SMC_CLC_DECLINE) &&<br>
> (clcm->type != expected_type))) {<br>
> smc->sk.sk_err = EPROTO;<br>
> @@ -331,16 +328,38 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,<br>
> goto out;<br>
> }<br>
> <br>
> + if (clcm->type == SMC_CLC_PROPOSAL && clcm->path == SMC_TYPE_N)<br>
> + reason_code = SMC_CLC_DECL_VERSMISMAT; /* just V2 offered */<br>
> +<br>
> /* receive the complete CLC message */<br>
> memset(&msg, 0, sizeof(struct msghdr));<br>
> - iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, datlen);<br>
> + if (datlen > buflen) {<br>
> + check_trl = false;<br>
> + recvlen = buflen;<br>
> + } else {<br>
> + recvlen = datlen;<br>
> + }<br>
> + iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, recvlen);<br>
> krflags = MSG_WAITALL;<br>
> len = sock_recvmsg(smc->clcsock, &msg, krflags);<br>
> - if (len < datlen || !smc_clc_msg_hdr_valid(clcm)) {<br>
> + if (len < recvlen || !smc_clc_msg_hdr_valid(clcm, check_trl)) {<br>
> smc->sk.sk_err = EPROTO;<br>
> reason_code = -EPROTO;<br>
> goto out;<br>
> }<br>
> + datlen -= len;<br>
> + while (datlen) {<br>
> + u8 tmp[SMC_CLC_RECV_BUF_LEN];<br>
> +<br>
> + vec.iov_base = &tmp;<br>
> + vec.iov_len = SMC_CLC_RECV_BUF_LEN;<br>
> + /* receive remaining proposal message */<br>
> + recvlen = datlen > SMC_CLC_RECV_BUF_LEN ?<br>
> + SMC_CLC_RECV_BUF_LEN : datlen;<br>
> + iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, recvlen);<br>
> + len = sock_recvmsg(smc->clcsock, &msg, krflags);<br>
> + datlen -= len;<br>
> + }<br>
> if (clcm->type == SMC_CLC_DECLINE) {<br>
> struct smc_clc_msg_decline *dclc;<br>
> <br>
> diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h<br>
> index ca209272e5fa..76c2b150d040 100644<br>
> --- a/net/smc/smc_clc.h<br>
> +++ b/net/smc/smc_clc.h<br>
> @@ -25,6 +25,7 @@<br>
> #define SMC_CLC_V1 0x1 /* SMC version */<br>
> #define SMC_TYPE_R 0 /* SMC-R only */<br>
> #define SMC_TYPE_D 1 /* SMC-D only */<br>
> +#define SMC_TYPE_N 2 /* neither SMC-R nor SMC-D */<br>
> #define SMC_TYPE_B 3 /* SMC-R and SMC-D */<br>
> #define CLC_WAIT_TIME (6 * HZ) /* max. wait time on clcsock */<br>
> #define CLC_WAIT_TIME_SHORT HZ /* short wait time on clcsock */<br>
> @@ -44,6 +45,9 @@<br>
> #define SMC_CLC_DECL_DIFFPREFIX 0x03070000 /* IP prefix / subnet mismatch */<br>
> #define SMC_CLC_DECL_GETVLANERR 0x03080000 /* err to get vlan id of ip device*/<br>
> #define SMC_CLC_DECL_ISMVLANERR 0x03090000 /* err to reg vlan id on ism dev */<br>
> +#define SMC_CLC_DECL_NOACTLINK 0x030a0000 /* no active smc-r link in lgr */<br>
> +#define SMC_CLC_DECL_NOSRVLINK 0x030b0000 /* SMC-R link from srv not found */<br>
> +#define SMC_CLC_DECL_VERSMISMAT 0x030c0000 /* SMC version mismatch */<br>
> #define SMC_CLC_DECL_SYNCERR 0x04000000 /* synchronization error */<br>
> #define SMC_CLC_DECL_PEERDECL 0x05000000 /* peer declined during handshake */<br>
> #define SMC_CLC_DECL_INTERR 0x09990000 /* internal error */<br>
> <br>
<br>
<br>
</blockquote></div>