nvme: fix potential memory leak in option parsing
authorChengguang Xu <cgxu519@gmx.com>
Sat, 14 Apr 2018 12:06:19 +0000 (20:06 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Jun 2018 19:02:53 +0000 (04:02 +0900)
[ Upstream commit 59a2f3f00fd744dbad22593f47552037d3154ca6 ]

When specifying same string type option several times,
current option parsing may cause memory leak. Hence,
call kfree for previous one in this case.

Signed-off-by: Chengguang Xu <cgxu519@gmx.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/nvme/host/fabrics.c

index 740aae51e1c6382f9038a6bc2696ec9da0c24b37..33d060c524e605ebc92d446993e6e0f84548b851 100644 (file)
@@ -587,6 +587,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
                                ret = -ENOMEM;
                                goto out;
                        }
+                       kfree(opts->transport);
                        opts->transport = p;
                        break;
                case NVMF_OPT_NQN:
@@ -595,6 +596,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
                                ret = -ENOMEM;
                                goto out;
                        }
+                       kfree(opts->subsysnqn);
                        opts->subsysnqn = p;
                        nqnlen = strlen(opts->subsysnqn);
                        if (nqnlen >= NVMF_NQN_SIZE) {
@@ -617,6 +619,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
                                ret = -ENOMEM;
                                goto out;
                        }
+                       kfree(opts->traddr);
                        opts->traddr = p;
                        break;
                case NVMF_OPT_TRSVCID:
@@ -625,6 +628,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
                                ret = -ENOMEM;
                                goto out;
                        }
+                       kfree(opts->trsvcid);
                        opts->trsvcid = p;
                        break;
                case NVMF_OPT_QUEUE_SIZE:
@@ -706,6 +710,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
                                ret = -EINVAL;
                                goto out;
                        }
+                       nvmf_host_put(opts->host);
                        opts->host = nvmf_host_add(p);
                        kfree(p);
                        if (!opts->host) {
@@ -731,6 +736,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
                                ret = -ENOMEM;
                                goto out;
                        }
+                       kfree(opts->host_traddr);
                        opts->host_traddr = p;
                        break;
                case NVMF_OPT_HOST_ID: