From: Dan Carpenter <dan.carpenter@oracle.com>
To: hiralpat@cisco.com
Cc: linux-scsi@vger.kernel.org
Subject: re: [SCSI] fnic: FIP VLAN Discovery Feature Support
Date: Wed, 8 Jan 2014 12:57:41 +0300 [thread overview]
Message-ID: <20140108095741.GA10666@elgon.mountain> (raw)
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
next reply other threads:[~2014-01-08 9:57 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-08 9:57 Dan Carpenter [this message]
2014-01-08 12:47 ` [SCSI] fnic: FIP VLAN Discovery Feature Support Dan Carpenter
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=20140108095741.GA10666@elgon.mountain \
--to=dan.carpenter@oracle.com \
--cc=hiralpat@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.