4.14-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Chengguang Xu <[email protected]>

[ Upstream commit 937441f3a3158d5510ca8cc78a82453f57a96365 ]

When parsing string option, in order to avoid memory leak we need to
carefully free it first in case of specifying same option several times.

Signed-off-by: Chengguang Xu <[email protected]>
Reviewed-by: Ilya Dryomov <[email protected]>
Signed-off-by: Ilya Dryomov <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
 fs/ceph/super.c        |    2 ++
 net/ceph/ceph_common.c |    7 +++++++
 2 files changed, 9 insertions(+)

--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -224,6 +224,7 @@ static int parse_fsopt_token(char *c, vo
                        return -ENOMEM;
                break;
        case Opt_mds_namespace:
+               kfree(fsopt->mds_namespace);
                fsopt->mds_namespace = kstrndup(argstr[0].from,
                                                argstr[0].to-argstr[0].from,
                                                GFP_KERNEL);
@@ -231,6 +232,7 @@ static int parse_fsopt_token(char *c, vo
                        return -ENOMEM;
                break;
        case Opt_fscache_uniq:
+               kfree(fsopt->fscache_uniq);
                fsopt->fscache_uniq = kstrndup(argstr[0].from,
                                               argstr[0].to-argstr[0].from,
                                               GFP_KERNEL);
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -418,11 +418,15 @@ ceph_parse_options(char *options, const
                                opt->flags |= CEPH_OPT_FSID;
                        break;
                case Opt_name:
+                       kfree(opt->name);
                        opt->name = kstrndup(argstr[0].from,
                                              argstr[0].to-argstr[0].from,
                                              GFP_KERNEL);
                        break;
                case Opt_secret:
+                       ceph_crypto_key_destroy(opt->key);
+                       kfree(opt->key);
+
                        opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
                        if (!opt->key) {
                                err = -ENOMEM;
@@ -433,6 +437,9 @@ ceph_parse_options(char *options, const
                                goto out;
                        break;
                case Opt_key:
+                       ceph_crypto_key_destroy(opt->key);
+                       kfree(opt->key);
+
                        opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
                        if (!opt->key) {
                                err = -ENOMEM;


Reply via email to