All of lore.kernel.org
 help / color / mirror / Atom feed
From: Roland Dreier <roland@purestorage.com>
To: "Nicholas A. Bellinger" <nab@linux-iscsi.org>
Cc: target-devel <target-devel@vger.kernel.org>,
	linux-scsi <linux-scsi@vger.kernel.org>,
	Andrew Vasquez <andrew.vasquez@qlogic.com>,
	Giridhar Malavali <giridhar.malavali@qlogic.com>,
	Christoph Hellwig <hch@lst.de>,
	James Bottomley <JBottomley@parallels.com>,
	Joern Engel <joern@logfs.org>,
	Madhuranath Iyengar <mni@risingtidesystems.com>
Subject: Re: [RFC-v4 3/3] qla2xxx: Add tcm_qla2xxx fabric module for mainline target
Date: Thu, 22 Dec 2011 00:10:44 -0800	[thread overview]
Message-ID: <CAL1RGDX-MR6pEwDN-vSjx92wUD3x5zk26UAG9QKpw1jp5-85mg@mail.gmail.com> (raw)
In-Reply-To: <1324173746-14361-4-git-send-email-nab@linux-iscsi.org>

Hi Nic,

On Sat, Dec 17, 2011 at 6:02 PM, Nicholas A. Bellinger
<nab@linux-iscsi.org> wrote:
> +/*
> + * Called from qla_target_template->free_cmd(), and will call
> + * tcm_qla2xxx_release_cmd via normal struct target_core_fabric_ops
> + * release callback.  qla_hw_data->hardware_lock is expected to be held
> + */
> +void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
> +{
> +       barrier();
> +       /*
> +        * Handle tcm_qla2xxx_init_cmd() -> transport_get_lun_for_cmd()
> +        * failure case where cmd->se_cmd.se_dev was not assigned, and
> +        * a call to transport_generic_free_cmd_intr() is not possible..
> +        */
> +       if (!cmd->se_cmd.se_dev) {
> +               target_put_sess_cmd(cmd->se_cmd.se_sess, &cmd->se_cmd);
> +               transport_generic_free_cmd(&cmd->se_cmd, 0);
> +               return;
> +       }
> +
> +       if (!atomic_read(&cmd->se_cmd.t_transport_complete))
> +               target_put_sess_cmd(cmd->se_cmd.se_sess, &cmd->se_cmd);
> +
> +       INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free);
> +       queue_work(tcm_qla2xxx_free_wq, &cmd->work);
> +}

can you explain why you do the second target_put_sess_cmd()
without a "return" here?  (the one when t_transport_complete == 0)

It seems this leads to use-after-free ... suppose cmd->execute_task in
__transport_execute_tasks() returns an error (eg due to malformed
emulated command from the initiator -- the easiest way to trigger this
is to do something like "sg_raw /dev/sda 12 00 00 00 00 00" on a
tcm_qla2xxx exported LUN).

Then we'll call transport_generic_request_failure()  which will end up
calling transport_cmd_check_stop_to_fabric(), which will call into
tcm_qla2xxx_check_stop_free(), which will do target_put_sess_cmd()
so we'll be down to 1 reference on the cmd.

Then when the HW finishes sending the SCSI status back, we'll
go into qla_tgt_do_ctio_completion(), which will call into ->free_cmd()
and end up in the function quoted above.

Since we failed the command we never call transport_complete_task()
so t_transport_complete will be 0 and we'll call target_put_sess_cmd()
a second time and therefore free the command immediately, and then
go ahead and queue up the work to free it a second time.

You can make this 100% reproducible and fatal by booting with
"slub_debug=FZUP" (or whatever the corresponding SLAB config
option is, I forget), and then doing some malformed emulated
command that ends up returning bad SCSI status (like the sg_raw
example above).

I still don't understand the command reference counting and freeing
scheme well enough to know what the right fix is here.  Are we
supposed to return after that put in the transport_complete==0 case?
But I thought we weren't supposed to free commands from interrupt
context, although I don't know what's wrong with doing what ends
up being just a kmem_cache_free() in the end.  So is doing the put in
the free_cmd function (which is called from the CTIO completion
handling interrupt context) OK?

Why do we have that put if t_transport_complete isn't set, anyway?
Doesn't the request failure path drop the reference?  Or is the problem
that we return SCSI status without setting t_transport_complete?

Thoughts?

 - R.

  reply	other threads:[~2011-12-22  8:10 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-18  2:02 [RFC-v4 0/3] qla2xxx: v3.4 target mode LLD changes + tcm_qla2xxx fabric module Nicholas A. Bellinger
2011-12-18  2:02 ` [RFC-v4 1/3] qla2xxx: Add LLD internal target-mode support Nicholas A. Bellinger
2011-12-19 22:59   ` Roland Dreier
2011-12-21 21:48     ` Nicholas A. Bellinger
2011-12-21 22:46       ` Roland Dreier
2011-12-18  2:02 ` [RFC-v4 2/3] qla2xxx: Enable 2xxx series LLD target mode support Nicholas A. Bellinger
2011-12-18  2:02 ` [RFC-v4 3/3] qla2xxx: Add tcm_qla2xxx fabric module for mainline target Nicholas A. Bellinger
2011-12-22  8:10   ` Roland Dreier [this message]
2011-12-23 21:51     ` Nicholas A. Bellinger
2012-01-02 21:38       ` Roland Dreier
2012-01-10  0:24         ` Nicholas A. Bellinger
2011-12-21 17:11 ` [RFC-v4 0/3] qla2xxx: v3.4 target mode LLD changes + tcm_qla2xxx fabric module Christoph Hellwig
2011-12-22 22:25   ` Andrew Vasquez
2011-12-23 21:59     ` Nicholas A. Bellinger

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=CAL1RGDX-MR6pEwDN-vSjx92wUD3x5zk26UAG9QKpw1jp5-85mg@mail.gmail.com \
    --to=roland@purestorage.com \
    --cc=JBottomley@parallels.com \
    --cc=andrew.vasquez@qlogic.com \
    --cc=giridhar.malavali@qlogic.com \
    --cc=hch@lst.de \
    --cc=joern@logfs.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=mni@risingtidesystems.com \
    --cc=nab@linux-iscsi.org \
    --cc=target-devel@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.