[Stgt-devel] [PATCH] task data leak
Pete Wyckoff
pw
Sat Dec 8 16:30:16 CET 2007
tomof at acm.org wrote on Sat, 08 Dec 2007 21:59 +0900:
> From: Pete Wyckoff <pw at osc.edu>
> Subject: [Stgt-devel] [PATCH] task data leak
> Date: Fri, 7 Dec 2007 15:23:53 -0500
>
> > iscsi_scsi_cmd_rx_start always allocates a buffer of 4096 to accommodate
> > assumptions in spc, sbc, etc. Even when a SCSI command asks for data
> > length of zero, task->data is allocated to 4096. However this is never
> > assigned as in or out buf on scmd. Thus never freed.
> >
> > This works around that by freeing an orphaned task->data. Again, though,
> > the better solution is to fix up all the little functions like inquiry
> > that cause this situation in the first place.
> >
> > Signed-off-by: Pete Wyckoff <pw at osc.edu>
> > ---
> > usr/iscsi/iscsid.c | 11 +++++++++++
> > 1 files changed, 11 insertions(+), 0 deletions(-)
> >
> > diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c
> > index 1e0172a..ab1999d 100644
> > --- a/usr/iscsi/iscsid.c
> > +++ b/usr/iscsi/iscsid.c
> > @@ -1024,6 +1024,17 @@ void iscsi_free_task(struct iscsi_task *task)
> > {
> > struct iscsi_connection *conn = task->conn;
> >
> > + /*
> > + * Catch case when data_len is zero but pushed up to 4096
> > + * to work around spc allocation assumption, but then later
> > + * determined to be DATA_NONE and not used as either in or
> > + * out buffer.
> > + */
> > + if (task->data &&
> > + task->data != scsi_get_in_buffer(&task->scmd) &&
> > + task->data != scsi_get_out_buffer(&task->scmd))
> > + conn->tp->free_data_buf(conn, task->data);
> > +
>
> Nice catch, thanks.
>
> How about this patch?
>
> diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c
> index 1e0172a..e27c74c 100644
> --- a/usr/iscsi/iscsid.c
> +++ b/usr/iscsi/iscsid.c
> @@ -1435,7 +1435,7 @@ static int iscsi_scsi_cmd_rx_start(struct iscsi_connection *conn)
> /*
> * fix spc, sbc, etc. they assume that buffer is long enough.
> */
> - if (data_len < 4096)
> + if (data_len && data_len < 4096)
> data_len = 4096;
>
> ext_len = ahs_len ? sizeof(req->cdb) + ahs_len : 0;
>
Would be simpler, yes, but less safe. Client could do an inquiry
with data_len of 0 and lead to a crash in spc_inquiry, e.g.
We really should just fix those functions. Adding a bunch of "if
(data_len > ...)" is one way, although one would need many of these
tests for all the various cases. I had proposed allocating a temp
buffer, then memcpy with bounds checking into whatever out_buffer is
available as the final step. See the old 03/20 iser-transport-buf
patch if you think that has merit.
The other issue is that inquiry etc. expect a zeroed buffer, and
trying to guess if scsi_is_io_opcode() to determine if the handler
function doesn't need zeroing is insufficient. I'll send a terrible
patch to work around this for OSD, but would prefer to fix inquiry
and friends instead.
-- Pete
More information about the stgt
mailing list