Skip to contentSkip to conversation

nvme_fc: Fix crash when nvme controller connection fails.

PATCH New James Smart 3 participants 3 messages Jun 16, 2017

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 nvme_fc: Fix crash when nvme controller connection fails.

If a controller connection is attempted (say to a subsystem that does not exist), the first attempt errors out. If another connect is attempted, it crashes.

Issue is the prior controller has yet execute it's final put, thus its still on lists. However, opts points on it have been cleared, thus causing the crash if they are referenced.

Fix is to add the missing put after the nvme_uninit_ctrl() call on the attachment failure.

Signed-off-by Paul Ely <Paul.Ely at broadcom.com>
Signed-off-by James Smart <james.smart at broadcom.com>
---
 drivers/nvme/host/fc.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/nvme/host/fc.c +3 -0
index 5165007e86a6..9700b45a3929 100644
@@ -2769,6 +2769,9 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
 		nvme_uninit_ctrl(&ctrl->ctrl);
 		nvme_put_ctrl(&ctrl->ctrl);
 
+		/* Remove core ctrl ref. */
+		nvme_put_ctrl(&ctrl->ctrl);
+
 		/* as we're past the point where we transition to the ref
 		 * counting teardown path, if we return a bad pointer here,
 		 * the calling routine, thinking it's prior to the
Signature · 1 line
2.11.0
#1 lore raw

PATCH 1/1 nvme_fc: Fix crash when nvme controller connection fails.

Quoted 22 lines · James Smart

If a controller connection is attempted (say to a subsystem that does not exist), the first attempt errors out. If another connect is attempted, it crashes.

Issue is the prior controller has yet execute it's final put, thus its still on lists. However, opts points on it have been cleared, thus causing the crash if they are referenced.

Fix is to add the missing put after the nvme_uninit_ctrl() call on the attachment failure.

Signed-off-by Paul Ely <Paul.Ely at broadcom.com>
Signed-off-by James Smart <james.smart at broadcom.com>
---
 drivers/nvme/host/fc.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/nvme/host/fc.c +0 -0
index 5165007e86a6..9700b45a3929 100644

drivers/nvme/host/fc.c nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, · line 2773

Quoted 5 lines
drivers/nvme/host/fc.c +2 -0
@@ -2769,6 +2769,9 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
 		nvme_uninit_ctrl(&ctrl->ctrl);
 		nvme_put_ctrl(&ctrl->ctrl);
 
+		/* Remove core ctrl ref. */
+		nvme_put_ctrl(&ctrl->ctrl);

So where is the additional reference vs the other transport drivers coming from?

#2 lore raw

PATCH 1/1 nvme_fc: Fix crash when nvme controller connection fails.

Quoted 26 lines · Christoph Hellwig
Quoted 25 lines · James Smart

If a controller connection is attempted (say to a subsystem that does not exist), the first attempt errors out. If another connect is attempted, it crashes.

Issue is the prior controller has yet execute it's final put, thus its still on lists. However, opts points on it have been cleared, thus causing the crash if they are referenced.

Fix is to add the missing put after the nvme_uninit_ctrl() call on the attachment failure.

Signed-off-by Paul Ely <Paul.Ely at broadcom.com>
Signed-off-by James Smart <james.smart at broadcom.com>
---
  drivers/nvme/host/fc.c | 3 +++
  1 file changed, 3 insertions(+)
drivers/nvme/host/fc.c +0 -0
index 5165007e86a6..9700b45a3929 100644
@@ -2769,6 +2769,9 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
  		nvme_uninit_ctrl(&ctrl->ctrl);
  		nvme_put_ctrl(&ctrl->ctrl);
 
Quoted 4 lines

drivers/nvme/host/fc.c nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, · line 2773

Quoted 2 lines
drivers/nvme/host/fc.c +2 -0
+		/* Remove core ctrl ref. */
+		nvme_put_ctrl(&ctrl->ctrl);

So where is the additional reference vs the other transport drivers coming from?

The different transports differ in their create/create association/delete association flows. This was a bug specific to nvme_fc's implementation - on a teardown on failure, called nvme_uninit_ctrl but didn't remove the final reference so the nvme controller goes away, with allows the nvme_fc controller to go away.

-- james