Skip to content

Commit

Permalink
net/smc: Avoid overwriting the copies of clcsock callback functions
Browse files Browse the repository at this point in the history
commit 1de9770 upstream.

The callback functions of clcsock will be saved and replaced during
the fallback. But if the fallback happens more than once, then the
copies of these callback functions will be overwritten incorrectly,
resulting in a loop call issue:

clcsk->sk_error_report
 |- smc_fback_error_report() <------------------------------|
     |- smc_fback_forward_wakeup()                          | (loop)
         |- clcsock_callback()  (incorrectly overwritten)   |
             |- smc->clcsk_error_report() ------------------|

So this patch fixes the issue by saving these function pointers only
once in the fallback and avoiding overwriting.

Reported-by: syzbot+4de3c0e8a263e1e499bc@syzkaller.appspotmail.com
Fixes: 341adee ("net/smc: Forward wakeup to smc socket waitqueue after fallback")
Link: https://lore.kernel.org/r/0000000000006d045e05d78776f6@google.com
Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Wen Gu authored and gregkh committed Feb 23, 2022
1 parent f8ba235 commit 7de7ba7
Showing 1 changed file with 7 additions and 3 deletions.
10 changes: 7 additions & 3 deletions net/smc/af_smc.c
Expand Up @@ -649,14 +649,17 @@ static void smc_fback_error_report(struct sock *clcsk)
static int smc_switch_to_fallback(struct smc_sock *smc, int reason_code)
{
struct sock *clcsk;
int rc = 0;

mutex_lock(&smc->clcsock_release_lock);
if (!smc->clcsock) {
mutex_unlock(&smc->clcsock_release_lock);
return -EBADF;
rc = -EBADF;
goto out;
}
clcsk = smc->clcsock->sk;

if (smc->use_fallback)
goto out;
smc->use_fallback = true;
smc->fallback_rsn = reason_code;
smc_stat_fallback(smc);
Expand All @@ -683,8 +686,9 @@ static int smc_switch_to_fallback(struct smc_sock *smc, int reason_code)
smc->clcsock->sk->sk_user_data =
(void *)((uintptr_t)smc | SK_USER_DATA_NOCOPY);
}
out:
mutex_unlock(&smc->clcsock_release_lock);
return 0;
return rc;
}

/* fall back during connect */
Expand Down

0 comments on commit 7de7ba7

Please sign in to comment.