All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: jhasan@marvell.com
Cc: linux-scsi@vger.kernel.org
Subject: [bug report] scsi: libfc: Free skb in fc_disc_gpn_id_resp() for valid cases
Date: Fri, 21 Aug 2020 15:52:26 +0300	[thread overview]
Message-ID: <20200821125226.GA34517@mwanda> (raw)

Hello Javed Hasan,

The patch ec007ef40abb: "scsi: libfc: Free skb in
fc_disc_gpn_id_resp() for valid cases" from Jul 29, 2020, leads to
the following static checker warning:

	drivers/scsi/libfc/fc_disc.c:638 fc_disc_gpn_id_resp()
	warn: '&fp->skb' double freed

drivers/scsi/libfc/fc_disc.c
   568  static void fc_disc_gpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
   569                                  void *rdata_arg)
   570  {
   571          struct fc_rport_priv *rdata = rdata_arg;
   572          struct fc_rport_priv *new_rdata;
   573          struct fc_lport *lport;
   574          struct fc_disc *disc;
   575          struct fc_ct_hdr *cp;
   576          struct fc_ns_gid_pn *pn;
   577          u64 port_name;
   578  
   579          lport = rdata->local_port;
   580          disc = &lport->disc;
   581  
   582          if (PTR_ERR(fp) == -FC_EX_CLOSED)
   583                  goto out;
   584          if (IS_ERR(fp)) {
   585                  mutex_lock(&disc->disc_mutex);
   586                  fc_disc_restart(disc);
   587                  mutex_unlock(&disc->disc_mutex);

This call to fc_disc_restart(disc); was added in the commit, but it
wasn't mentioned in the commit message so I suspect it was committed by
mistake.

   588                  goto out;
   589          }
   590  
   591          cp = fc_frame_payload_get(fp, sizeof(*cp));
   592          if (!cp)
   593                  goto redisc;
   594          if (ntohs(cp->ct_cmd) == FC_FS_ACC) {
   595                  if (fr_len(fp) < sizeof(struct fc_frame_header) +
   596                      sizeof(*cp) + sizeof(*pn))
   597                          goto redisc;
   598                  pn = (struct fc_ns_gid_pn *)(cp + 1);
   599                  port_name = get_unaligned_be64(&pn->fn_wwpn);
   600                  mutex_lock(&rdata->rp_mutex);
   601                  if (rdata->ids.port_name == -1)
   602                          rdata->ids.port_name = port_name;
   603                  else if (rdata->ids.port_name != port_name) {
   604                          FC_DISC_DBG(disc, "GPN_ID accepted.  WWPN changed. "
   605                                      "Port-id %6.6x wwpn %16.16llx\n",
   606                                      rdata->ids.port_id, port_name);
   607                          mutex_unlock(&rdata->rp_mutex);
   608                          fc_rport_logoff(rdata);
   609                          mutex_lock(&lport->disc.disc_mutex);
   610                          new_rdata = fc_rport_create(lport, rdata->ids.port_id);
   611                          mutex_unlock(&lport->disc.disc_mutex);
   612                          if (new_rdata) {
   613                                  new_rdata->disc_id = disc->disc_id;
   614                                  fc_rport_login(new_rdata);
   615                          }
   616                          goto free_fp;
   617                  }
   618                  rdata->disc_id = disc->disc_id;
   619                  mutex_unlock(&rdata->rp_mutex);
   620                  fc_rport_login(rdata);
   621          } else if (ntohs(cp->ct_cmd) == FC_FS_RJT) {
   622                  FC_DISC_DBG(disc, "GPN_ID rejected reason %x exp %x\n",
   623                              cp->ct_reason, cp->ct_explan);
   624                  fc_rport_logoff(rdata);
   625          } else {
   626                  FC_DISC_DBG(disc, "GPN_ID unexpected response code %x\n",
   627                              ntohs(cp->ct_cmd));
   628  redisc:
   629                  mutex_lock(&disc->disc_mutex);
   630                  fc_disc_restart(disc);
   631                  mutex_unlock(&disc->disc_mutex);
   632          }
   633  free_fp:
   634          fc_frame_free(fp);
                ^^^^^^^^^^^^^^^^^
Then this free was added.


   635  out:
   636          kref_put(&rdata->kref, fc_rport_destroy);
   637          if (!IS_ERR(fp))
   638                  fc_frame_free(fp);
                        ^^^^^^^^^^^^^^^^^
But there was already a free here so it was a double free.

   639  }

regards,
dan carpenter

             reply	other threads:[~2020-08-21 12:52 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-21 12:52 Dan Carpenter [this message]
2020-08-27  7:35 ` [EXT] [bug report] scsi: libfc: Free skb in fc_disc_gpn_id_resp() for valid cases Javed Hasan

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=20200821125226.GA34517@mwanda \
    --to=dan.carpenter@oracle.com \
    --cc=jhasan@marvell.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.