diff mbox

ceph: avoid memory leak when specifying same option several times

Message ID 1517876755-46814-1-git-send-email-cgxu519@icloud.com (mailing list archive)
State New, archived
Headers show

Commit Message

Chengguang Xu Feb. 6, 2018, 12:25 a.m. UTC
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 <cgxu519@icloud.com>
---
 fs/ceph/super.c        | 2 ++
 net/ceph/ceph_common.c | 7 +++++++
 2 files changed, 9 insertions(+)

Comments

Ilya Dryomov Feb. 6, 2018, 10:26 a.m. UTC | #1
On Tue, Feb 6, 2018 at 1:25 AM, Chengguang Xu <cgxu519@icloud.com> wrote:
> 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 <cgxu519@icloud.com>
> ---
>  fs/ceph/super.c        | 2 ++
>  net/ceph/ceph_common.c | 7 +++++++
>  2 files changed, 9 insertions(+)
>
> diff --git a/fs/ceph/super.c b/fs/ceph/super.c
> index a62d2a9..bfc85b2 100644
> --- a/fs/ceph/super.c
> +++ b/fs/ceph/super.c
> @@ -225,6 +225,7 @@ static int parse_fsopt_token(char *c, void *private)
>                         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);
> @@ -232,6 +233,7 @@ static int parse_fsopt_token(char *c, void *private)
>                         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);
> diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
> index 5c036d2..cdb5b69 100644
> --- a/net/ceph/ceph_common.c
> +++ b/net/ceph/ceph_common.c
> @@ -418,11 +418,15 @@ struct ceph_options *
>                                 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 @@ struct ceph_options *
>                                 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;

Applied.

Thanks,

                Ilya
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index a62d2a9..bfc85b2 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -225,6 +225,7 @@  static int parse_fsopt_token(char *c, void *private)
 			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);
@@ -232,6 +233,7 @@  static int parse_fsopt_token(char *c, void *private)
 			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);
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 5c036d2..cdb5b69 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -418,11 +418,15 @@  struct ceph_options *
 				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 @@  struct ceph_options *
 				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;