All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: Anantha Prakash T <atungara@cisco.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [SCSI] fnic: FIP VLAN Discovery Feature Support
Date: Wed, 8 Jan 2014 15:47:30 +0300	[thread overview]
Message-ID: <20140108124730.GR5443@mwanda> (raw)
In-Reply-To: <20140108095741.GA10666@elgon.mountain>

Hiral isn't at Cisco any more.

regards,
dan carpenter

On Wed, Jan 08, 2014 at 12:57:41PM +0300, Dan Carpenter wrote:
> Hello Hiral Patel,
> 
> The patch d3c995f1dcf9: "[SCSI] fnic: FIP VLAN Discovery Feature
> Support" from Feb 25, 2013, leads to the following
> static checker warning:
> 
> 	drivers/scsi/fnic/fnic_fcs.c:278 is_fnic_fip_flogi_reject()
> 	warn: is it ok to set 'els_len' to negative?
> 
> This is some unpushable debug code on my Smatch system.  It is sort of
> a nonsense warning because Smatch has run into an "impossible" condition
> because of a bug in Smatch but also because of bug in
> fnic_fcoe_send_vlan_req().
> 
> drivers/scsi/fnic/fnic_fcs.c
>    251          fiph = (struct fip_header *)skb->data;
>                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> fiph is untrusted data.  We don't trust the network.  This is a rule of
> Linux.
> 
>    252          op = ntohs(fiph->fip_op);
>    253          sub = fiph->fip_subcode;
>    254  
>    255          if (op != FIP_OP_LS)
>    256                  return 0;
>    257  
>    258          if (sub != FIP_SC_REP)
>    259                  return 0;
>    260  
>    261          rlen = ntohs(fiph->fip_dl_len) * 4;
>    262          if (rlen + sizeof(*fiph) > skb->len)
>    263                  return 0;
>    264  
>    265          desc = (struct fip_desc *)(fiph + 1);
>    266          dlen = desc->fip_dlen * FIP_BPW;
>                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> desc->fip_dlen is u8 type so it could be a number between 0-255.  That's
> fine.
> FIP_BPW is 4.
> Here is the bug in Smatch.  It looks at the sender code and says that
> desc->fip_dlen is set to either 2 or 4.  So now dlen is in 8-16 range.
> 
>    267  
>    268          if (desc->fip_dtype == FIP_DT_FLOGI) {
>    269  
>    270                  shost_printk(KERN_DEBUG, lport->host,
>    271                            " FIP TYPE FLOGI: fab name:%llx "
>    272                            "vfid:%d map:%x\n",
>    273                            fip->sel_fcf->fabric_name, fip->sel_fcf->vfid,
>    274                            fip->sel_fcf->fc_map);
>    275                  if (dlen < sizeof(*els) + sizeof(*fh) + 1)
>                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 8-16 is always less than 29 so this condition is always true.
> 
>    276                          return 0;
>    277  
>    278                  els_len = dlen - sizeof(*els);
>                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> We are in an impossible condition and Smatch doesn't know the possible
> values of "dlen" any more so it generates the warning.
> 
>    279                  els = (struct fip_encaps *)desc;
>    280                  fh = (struct fc_frame_header *)(els + 1);
>    281                  els_dtype = desc->fip_dtype;
>    282  
>    283                  if (!fh)
>    284                          return 0;
>    285  
>    286                  /*
>    287                   * ELS command code, reason and explanation should be = Reject,
>    288                   * unsupported command and insufficient resource
>    289                   */
>    290                  els_op = *(u8 *)(fh + 1);
>    291                  if (els_op == ELS_LS_RJT) {
>    292                          shost_printk(KERN_INFO, lport->host,
>    293                                    "Flogi Request Rejected by Switch\n");
>    294                          return 1;
>    295                  }
>    296                  shost_printk(KERN_INFO, lport->host,
>    297                                  "Flogi Request Accepted by Switch\n");
>    298          }
>    299          return 0;
>    300  }
>    301  
>    302  static void fnic_fcoe_send_vlan_req(struct fnic *fnic)
>    303  {
>    304          struct fcoe_ctlr *fip = &fnic->ctlr;
>    305          struct fnic_stats *fnic_stats = &fnic->fnic_stats;
>    306          struct sk_buff *skb;
>    307          char *eth_fr;
>    308          int fr_len;
>    309          struct fip_vlan *vlan;
>    310          u64 vlan_tov;
>    311  
>    312          fnic_fcoe_reset_vlans(fnic);
>    313          fnic->set_vlan(fnic, 0);
>    314          FNIC_FCS_DBG(KERN_INFO, fnic->lport->host,
>    315                    "Sending VLAN request...\n");
>    316          skb = dev_alloc_skb(sizeof(struct fip_vlan));
>    317          if (!skb)
>    318                  return;
>    319  
>    320          fr_len = sizeof(*vlan);
>    321          eth_fr = (char *)skb->data;
>    322          vlan = (struct fip_vlan *)eth_fr;
>    323  
>    324          memset(vlan, 0, sizeof(*vlan));
>    325          memcpy(vlan->eth.h_source, fip->ctl_src_addr, ETH_ALEN);
>    326          memcpy(vlan->eth.h_dest, fcoe_all_fcfs, ETH_ALEN);
>    327          vlan->eth.h_proto = htons(ETH_P_FIP);
>    328  
>    329          vlan->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
>    330          vlan->fip.fip_op = htons(FIP_OP_VLAN);
>    331          vlan->fip.fip_subcode = FIP_SC_VL_REQ;
>    332          vlan->fip.fip_dl_len = htons(sizeof(vlan->desc) / FIP_BPW);
>    333  
>    334          vlan->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC;
>    335          vlan->desc.mac.fd_desc.fip_dlen = sizeof(vlan->desc.mac) / FIP_BPW;
> 
> 8 / 4 = 2.  We are setting ->fib_dlen to 2.
> 
>    336          memcpy(&vlan->desc.mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
>    337  
>    338          vlan->desc.wwnn.fd_desc.fip_dtype = FIP_DT_NAME;
>    339          vlan->desc.wwnn.fd_desc.fip_dlen = sizeof(vlan->desc.wwnn) / FIP_BPW;
>                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> This is actually a second Smatch bug which it inherited from Sparse.  It
> doesn't understand packed structs correctly and think we are setting
> ->fib_dlen to 4 but we are setting it to 3.
> 
>    340          put_unaligned_be64(fip->lp->wwnn, &vlan->desc.wwnn.fd_wwn);
>    341          atomic64_inc(&fnic_stats->vlan_stats.vlan_disc_reqs);
>    342  
> 
> I suspect that the size calculation is not taking
> sizeof(struct fc_frame_header) into consideration properly in
> fnic_fcoe_send_vlan_req()?
> 
> regards,
> dan carpenter

      reply	other threads:[~2014-01-08 12:47 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-08  9:57 [SCSI] fnic: FIP VLAN Discovery Feature Support Dan Carpenter
2014-01-08 12:47 ` Dan Carpenter [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140108124730.GR5443@mwanda \
    --to=dan.carpenter@oracle.com \
    --cc=atungara@cisco.com \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.