[bug report] nfsd: Protect session creation and client confirm using client_lock

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

 



Hello Jeff Layton,

The patch d20c11d86d8f: "nfsd: Protect session creation and client
confirm using client_lock" from Jul 30, 2014, leads to the following
Smatch static checker warning:

	net/sunrpc/addr.c:178 rpc_parse_scope_id()
	warn: sleeping in atomic context

net/sunrpc/addr.c
    161 static int rpc_parse_scope_id(struct net *net, const char *buf,
    162                               const size_t buflen, const char *delim,
    163                               struct sockaddr_in6 *sin6)
    164 {
    165         char *p;
    166         size_t len;
    167 
    168         if ((buf + buflen) == delim)
    169                 return 1;
    170 
    171         if (*delim != IPV6_SCOPE_DELIMITER)
    172                 return 0;
    173 
    174         if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
    175                 return 0;
    176 
    177         len = (buf + buflen) - delim - 1;
--> 178         p = kmemdup_nul(delim + 1, len, GFP_KERNEL);
    179         if (p) {
    180                 u32 scope_id = 0;
    181                 struct net_device *dev;
    182 
    183                 dev = dev_get_by_name(net, p);
    184                 if (dev != NULL) {
    185                         scope_id = dev->ifindex;
    186                         dev_put(dev);
    187                 } else {
    188                         if (kstrtou32(p, 10, &scope_id) != 0) {
    189                                 kfree(p);
    190                                 return 0;
    191                         }
    192                 }
    193 
    194                 kfree(p);
    195 
    196                 sin6->sin6_scope_id = scope_id;
    197                 return 1;
    198         }
    199 
    200         return 0;
    201 }

The call tree is:

nfsd4_setclientid() <- disables preempt
-> gen_callback()
   -> rpc_uaddr2sockaddr()
      -> rpc_pton()
         -> rpc_pton6()
            -> rpc_parse_scope_id()

The commit added a spin_lock to nfsd4_setclientid().

fs/nfsd/nfs4state.c
  4023                          trace_nfsd_clid_verf_mismatch(conf, rqstp,
  4024                                                        &clverifier);
  4025          } else
  4026                  trace_nfsd_clid_fresh(new);
  4027          new->cl_minorversion = 0;
  4028          gen_callback(new, setclid, rqstp);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  4029          add_to_unconfirmed(new);
  4030          setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
  4031          setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
  4032          memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
  4033          new = NULL;
  4034          status = nfs_ok;
  4035  out:
  4036          spin_unlock(&nn->client_lock);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is the new lock.

  4037          if (new)
  4038                  free_client(new);
  4039          if (unconf) {
  4040                  trace_nfsd_clid_expire_unconf(&unconf->cl_clientid);
  4041                  expire_client(unconf);
  4042          }
  4043          return status;

regards,
dan carpenter



[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux