Re: [bug report] net/smc: CLC accept / confirm V2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 10/28/20 12:25 PM, Dan Carpenter wrote:
> Hello Ursula Braun,
> 
> The patch a7c9c5f4af7f: "net/smc: CLC accept / confirm V2" from Sep
> 26, 2020, leads to the following static checker warning:
> 
> 	net/smc/af_smc.c:1771 smc_listen_work()
> 	error: we previously assumed 'ini' could be null (see line 1715)
> 

Thanks for reporting this problem!
Karsten Graul provided already this fix on 10/23/20 (accepted by
Jakub Kicinski 10/27/20) for the net-tree:

   net/smc: fix null pointer dereference in smc_listen_decline()

   smc_listen_work() calls smc_listen_decline() on label out_decl,
   providing the ini pointer variable. But this pointer can still be null
   when the label out_decl is reached.
   Fix this by checking the ini variable in smc_listen_work() and call
   smc_listen_decline() with the result directly.

   Fixes: a7c9c5f4af7f ("net/smc: CLC accept / confirm V2")
   Signed-off-by: Karsten Graul <kgraul@xxxxxxxxxxxxx>

This fix is supposed to solve your reported problem.

Regards, Ursula Braun

> net/smc/af_smc.c
>   1665  static void smc_listen_work(struct work_struct *work)
>   1666  {
>   1667          struct smc_sock *new_smc = container_of(work, struct smc_sock,
>   1668                                                  smc_listen_work);
>   1669          u8 version = smc_ism_v2_capable ? SMC_V2 : SMC_V1;
>   1670          struct socket *newclcsock = new_smc->clcsock;
>   1671          struct smc_clc_msg_accept_confirm *cclc;
>   1672          struct smc_clc_msg_proposal_area *buf;
>   1673          struct smc_clc_msg_proposal *pclc;
>   1674          struct smc_init_info *ini = NULL;
>                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
>   1675          int rc = 0;
>   1676  
>   1677          if (new_smc->listen_smc->sk.sk_state != SMC_LISTEN)
>   1678                  return smc_listen_out_err(new_smc);
>   1679  
>   1680          if (new_smc->use_fallback) {
>   1681                  smc_listen_out_connected(new_smc);
>   1682                  return;
>   1683          }
>   1684  
>   1685          /* check if peer is smc capable */
>   1686          if (!tcp_sk(newclcsock->sk)->syn_smc) {
>   1687                  smc_switch_to_fallback(new_smc);
>   1688                  new_smc->fallback_rsn = SMC_CLC_DECL_PEERNOSMC;
>   1689                  smc_listen_out_connected(new_smc);
>   1690                  return;
>   1691          }
>   1692  
>   1693          /* do inband token exchange -
>   1694           * wait for and receive SMC Proposal CLC message
>   1695           */
>   1696          buf = kzalloc(sizeof(*buf), GFP_KERNEL);
>   1697          if (!buf) {
>   1698                  rc = SMC_CLC_DECL_MEM;
>   1699                  goto out_decl;
>                         ^^^^^^^^^^^^^^
> There are several paths where "ini" is NULL leading to an Oops in the
> error handling.
> 
>   1700          }
>   1701          pclc = (struct smc_clc_msg_proposal *)buf;
>   1702          rc = smc_clc_wait_msg(new_smc, pclc, sizeof(*buf),
>   1703                                SMC_CLC_PROPOSAL, CLC_WAIT_TIME);
>   1704          if (rc)
>   1705                  goto out_decl;
>                         ^^^^^^^^^^^^^
> 
>   1706          version = pclc->hdr.version == SMC_V1 ? SMC_V1 : version;
>   1707  
>   1708          /* IPSec connections opt out of SMC optimizations */
>   1709          if (using_ipsec(new_smc)) {
>   1710                  rc = SMC_CLC_DECL_IPSEC;
>   1711                  goto out_decl;
>                         ^^^^^^^^^^^^^
> 
>   1712          }
>   1713  
>   1714          ini = kzalloc(sizeof(*ini), GFP_KERNEL);
>   1715          if (!ini) {
>   1716                  rc = SMC_CLC_DECL_MEM;
>   1717                  goto out_decl;
>                         ^^^^^^^^^^^^^
> 
>   1718          }
>   1719  
>   1720          /* initial version checking */
>   1721          rc = smc_listen_v2_check(new_smc, pclc, ini);
>   1722          if (rc)
>   1723                  goto out_decl;
>   1724  
>   1725          mutex_lock(&smc_server_lgr_pending);
>   1726          smc_close_init(new_smc);
>   1727          smc_rx_init(new_smc);
>   1728          smc_tx_init(new_smc);
>   1729  
>   1730          /* determine ISM or RoCE device used for connection */
>   1731          rc = smc_listen_find_device(new_smc, pclc, ini);
>   1732          if (rc)
>   1733                  goto out_unlock;
>   1734  
>   1735          /* send SMC Accept CLC message */
>   1736          rc = smc_clc_send_accept(new_smc, ini->first_contact_local,
>   1737                                   ini->smcd_version == SMC_V2 ? SMC_V2 : SMC_V1);
>   1738          if (rc)
>   1739                  goto out_unlock;
>   1740  
>   1741          /* SMC-D does not need this lock any more */
>   1742          if (ini->is_smcd)
>   1743                  mutex_unlock(&smc_server_lgr_pending);
>   1744  
>   1745          /* receive SMC Confirm CLC message */
>   1746          memset(buf, 0, sizeof(*buf));
>   1747          cclc = (struct smc_clc_msg_accept_confirm *)buf;
>   1748          rc = smc_clc_wait_msg(new_smc, cclc, sizeof(*buf),
>   1749                                SMC_CLC_CONFIRM, CLC_WAIT_TIME);
>   1750          if (rc) {
>   1751                  if (!ini->is_smcd)
>   1752                          goto out_unlock;
>   1753                  goto out_decl;
>   1754          }
>   1755  
>   1756          /* finish worker */
>   1757          if (!ini->is_smcd) {
>   1758                  rc = smc_listen_rdma_finish(new_smc, cclc,
>   1759                                              ini->first_contact_local);
>   1760                  if (rc)
>   1761                          goto out_unlock;
>   1762                  mutex_unlock(&smc_server_lgr_pending);
>   1763          }
>   1764          smc_conn_save_peer_info(new_smc, cclc);
>   1765          smc_listen_out_connected(new_smc);
>   1766          goto out_free;
>   1767  
>   1768  out_unlock:
>   1769          mutex_unlock(&smc_server_lgr_pending);
>   1770  out_decl:
>   1771          smc_listen_decline(new_smc, rc, ini, version);
>                                                 ^^^
> If "ini" is NULL then this will Oops.
> 
>   1772  out_free:
>   1773          kfree(ini);
>   1774          kfree(buf);
>   1775  }
> 
> regards,
> dan carpenter
> 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Kernel Development]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Info]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Linux Media]     [Device Mapper]

  Powered by Linux