bdev_iscsi: fix crash when connecting to a non existing iqn
When connecting to an iscsi url that effectively does not exist we free the data structures of the very context we are processing. This results in a use after free and subsequently in a crash. Signed-off-by: Jeffry Molanus <jeffry.molanus@gmail.com> Change-Id: I67cab1efb161bfa23fa1022e150661080d90b556 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/462614 Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Jeffry Molanus <Jeffry.molanus@gmail.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
ed56a3d482
commit
bc315deae3
@ -98,9 +98,10 @@ struct bdev_iscsi_conn_req {
|
|||||||
char *initiator_iqn;
|
char *initiator_iqn;
|
||||||
struct iscsi_context *context;
|
struct iscsi_context *context;
|
||||||
spdk_bdev_iscsi_create_cb create_cb;
|
spdk_bdev_iscsi_create_cb create_cb;
|
||||||
spdk_bdev_iscsi_create_cb create_cb_arg;
|
void *create_cb_arg;
|
||||||
bool unmap_supported;
|
bool unmap_supported;
|
||||||
int lun;
|
int lun;
|
||||||
|
int status;
|
||||||
TAILQ_ENTRY(bdev_iscsi_conn_req) link;
|
TAILQ_ENTRY(bdev_iscsi_conn_req) link;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -110,17 +111,12 @@ complete_conn_req(struct bdev_iscsi_conn_req *req, struct spdk_bdev *bdev,
|
|||||||
{
|
{
|
||||||
TAILQ_REMOVE(&g_iscsi_conn_req, req, link);
|
TAILQ_REMOVE(&g_iscsi_conn_req, req, link);
|
||||||
req->create_cb(req->create_cb_arg, bdev, status);
|
req->create_cb(req->create_cb_arg, bdev, status);
|
||||||
if (status) {
|
|
||||||
/* if the request failed and no iscsi lun was
|
/*
|
||||||
* created then we could not hand over this
|
* we are still running in the context of iscsi_service()
|
||||||
* memory and have to free it manually now.
|
* so do not tear down its data structures here
|
||||||
*/
|
*/
|
||||||
iscsi_destroy_context(req->context);
|
req->status = status;
|
||||||
free(req->initiator_iqn);
|
|
||||||
free(req->bdev_name);
|
|
||||||
free(req->url);
|
|
||||||
}
|
|
||||||
free(req);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -145,14 +141,29 @@ _iscsi_free_lun(void *arg)
|
|||||||
free(lun);
|
free(lun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_bdev_iscsi_conn_req_free(struct bdev_iscsi_conn_req *req)
|
||||||
|
{
|
||||||
|
|
||||||
|
free(req->initiator_iqn);
|
||||||
|
free(req->bdev_name);
|
||||||
|
free(req->url);
|
||||||
|
/* destroy will call iscsi_disconnect() implicitly if connected */
|
||||||
|
iscsi_destroy_context(req->context);
|
||||||
|
free(req);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bdev_iscsi_finish(void)
|
bdev_iscsi_finish(void)
|
||||||
{
|
{
|
||||||
struct bdev_iscsi_conn_req *req;
|
struct bdev_iscsi_conn_req *req, *tmp;
|
||||||
|
|
||||||
while (!TAILQ_EMPTY(&g_iscsi_conn_req)) {
|
/* clear out pending connection requests here. We cannot
|
||||||
req = TAILQ_FIRST(&g_iscsi_conn_req);
|
* simply set the state to a non SCSI_STATUS_GOOD state as
|
||||||
complete_conn_req(req, NULL, -EINTR);
|
* the connection poller wont run anymore
|
||||||
|
*/
|
||||||
|
TAILQ_FOREACH_SAFE(req, &g_iscsi_conn_req, link, tmp) {
|
||||||
|
_bdev_iscsi_conn_req_free(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_conn_poller) {
|
if (g_conn_poller) {
|
||||||
@ -725,8 +736,16 @@ iscsi_bdev_conn_poll(void *arg)
|
|||||||
SPDK_ERRLOG("iscsi_service failed: %s\n", iscsi_get_error(context));
|
SPDK_ERRLOG("iscsi_service failed: %s\n", iscsi_get_error(context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if (req->status != SCSI_STATUS_GOOD) {
|
||||||
|
/*
|
||||||
|
* An error has occurred during connecting. This req has already
|
||||||
|
* been removed from the g_iscsi_conn_req list, but we needed to
|
||||||
|
* wait until iscsi_service unwound before we could free the req.
|
||||||
|
*/
|
||||||
|
_bdev_iscsi_conn_req_free(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -748,6 +767,7 @@ create_iscsi_disk(const char *bdev_name, const char *url, const char *initiator_
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req->status = SCSI_STATUS_GOOD;
|
||||||
req->bdev_name = strdup(bdev_name);
|
req->bdev_name = strdup(bdev_name);
|
||||||
req->url = strdup(url);
|
req->url = strdup(url);
|
||||||
req->initiator_iqn = strdup(initiator_iqn);
|
req->initiator_iqn = strdup(initiator_iqn);
|
||||||
|
Loading…
Reference in New Issue
Block a user