Re: [bug report] cifs: Send witness register and unregister commands to userspace daemon

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

 



On Tue, 2020-12-15 at 17:45 +0300, Dan Carpenter wrote:
> Hello Samuel Cabrero,
> 
> The patch bf80e5d4259a: "cifs: Send witness register and unregister
> commands to userspace daemon" from Nov 30, 2020, leads to the
> following static checker warning:
> 
>         fs/cifs/cifs_swn.c:265 cifs_find_swn_reg()
>         warn: passing a valid pointer to 'PTR_ERR'
> 
> fs/cifs/cifs_swn.c
>    254  static struct cifs_swn_reg *cifs_find_swn_reg(struct
> cifs_tcon *tcon)
>    255  {
>    256          struct cifs_swn_reg *swnreg;
>    257          int id;
>    258          const char *share_name;
>    259          const char *net_name;
>    260  
>    261          net_name = extract_hostname(tcon->treeName);
>    262          if (IS_ERR_OR_NULL(net_name)) {
>    263                  int ret;
>    264  
>    265                  ret = PTR_ERR(net_name);
>                         ^^^^^^^^^^^^^^^^^^^^^^^
> 
> When a function returns *both* error pointers and NULL then NULL is
> not
> an error.  Probably it's an optional feature which has been disabled.
> If the function returns an error pointer then the function needs to
> clean up and fail in the proper way.  Maybe print an error message. 
> If
> it returns NULL then that means the feature has been diliberately
> disabled.  Don't print an error code.
> 
> The extract_hostname() is not optional and never returns NULL
> pointers.
> 
>    266                  cifs_dbg(VFS, "%s: failed to extract host
> name from target '%s': %d\n",
>    267                                  __func__, tcon->treeName,
> ret);
>    268                  return NULL;
>                         ^^^^^^^^^^^^
> 
> I guess probably the intention was to return an error pointer here
> and
> a NULL if we were able to search for the existing swn reg.  But
> probably
> it's simpler to just return either error pointers or NULLs on error
> and
> be consistent about it.  There is no point in optimizing for the
> failure
> case because that's not a fast path and it will just lead to bugs.
> 
> This function has two callers and one checks for both NULL and error
> pointers and the other only checks for NULLs so returning an error
> pointer would lead to bugs.
> 
>    269          }
>    270  
>    271          share_name = extract_sharename(tcon->treeName);
>    272          if (IS_ERR_OR_NULL(share_name)) {
>    273                  int ret;
>    274  
>    275                  ret = PTR_ERR(net_name);
>    276                  cifs_dbg(VFS, "%s: failed to extract share
> name from target '%s': %d\n",
>    277                                  __func__, tcon->treeName,
> ret);
>    278                  kfree(net_name);
>    279                  return NULL;
>    280          }
>    281  
>    282          idr_for_each_entry(&cifs_swnreg_idr, swnreg, id) {
>    283                  if (strcasecmp(swnreg->net_name, net_name) !=
> 0
>    284                      || strcasecmp(swnreg->share_name,
> share_name) != 0) {
>    285                          continue;
>    286                  }
>    287  
>    288                  mutex_unlock(&cifs_swnreg_idr_mutex);
>    289  
>    290                  cifs_dbg(FYI, "Existing swn registration for
> %s:%s found\n", swnreg->net_name,
>    291                                  swnreg->share_name);
>    292  
>    293                  kfree(net_name);
>    294                  kfree(share_name);
>    295  
>    296                  return swnreg;
>    297          }
>    298  
>    299          kfree(net_name);
>    300          kfree(share_name);
>    301  
>    302          return NULL;
>    303  }
> 
> [ snip ]
> 
>    309  static struct cifs_swn_reg *cifs_get_swn_reg(struct cifs_tcon
> *tcon)
>    310  {
>    311          struct cifs_swn_reg *reg = NULL;
>    312          int ret;
>    313  
>    314          mutex_lock(&cifs_swnreg_idr_mutex);
>    315  
>    316          /* Check if we are already registered for this
> network and share names */
>    317          reg = cifs_find_swn_reg(tcon);
>    318          if (IS_ERR(reg)) {
>    319                  return reg;
> 
> This code checks for errors but the cifs_find_swn_reg() function only
> returns NULL or valid pointers.
> 
>    320          } else if (reg != NULL) {
>    321                  kref_get(&reg->ref_count);
>    322                  mutex_unlock(&cifs_swnreg_idr_mutex);
>    323                  return reg;
>    324          }
>    325  
>    326          reg = kmalloc(sizeof(struct cifs_swn_reg),
> GFP_ATOMIC);
>    327          if (reg == NULL) {
>    328                  mutex_unlock(&cifs_swnreg_idr_mutex);
>    329                  return ERR_PTR(-ENOMEM);
>    330          }
> 
> regards,
> dan carpenter

Hello Dan,

thank you for the feedback and the detailed analysis. I wanted to refer
to this email in the patch I have just send to the list but I have to
improve my git send-email knowledge first.

Regards,

-- 
Samuel Cabrero / SUSE Labs Samba Team
GPG: D7D6 E259 F91C F0B3 2E61 1239 3655 6EC9 7051 0856
scabrero@xxxxxxxx
scabrero@xxxxxxx




[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux