linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: Eric Biggers <ebiggers3@gmail.com>
Cc: dhowells@redhat.com, Alexander Viro <viro@zeniv.linux.org.uk>,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	Eric Biggers <ebiggers@google.com>
Subject: Re: [PATCH 07/18] fs_context: fix double free of legacy_fs_context data
Date: Tue, 10 Jul 2018 09:02:04 +0100	[thread overview]
Message-ID: <25103.1531209724@warthog.procyon.org.uk> (raw)
In-Reply-To: <20180710011741.GA1014@sol.localdomain>

Eric Biggers <ebiggers3@gmail.com> wrote:

> Why isn't this done in the same place that ->init_fs_context() would otherwise
> be called?  It logically does the same thing, right?

Fair point.  How about the attached incremental change?  It breaks the legacy
context initialisation out into its own init function and just sets that as
the default if the fs doesn't supply its own.

It also makes the freeing conditional.

David
---
diff --git a/fs/fs_context.c b/fs/fs_context.c
index 8af0542ab8b6..f388ab29d37d 100644
--- a/fs/fs_context.c
+++ b/fs/fs_context.c
@@ -42,6 +42,7 @@ struct legacy_fs_context {
 	enum legacy_fs_param	param_type;
 };
 
+static int legacy_init_fs_context(struct fs_context *fc, struct dentry *dentry);
 static const struct fs_context_operations legacy_fs_context_ops;
 
 static const match_table_t common_set_sb_flag = {
@@ -239,6 +240,7 @@ struct fs_context *vfs_new_fs_context(struct file_system_type *fs_type,
 				      unsigned int sb_flags,
 				      enum fs_context_purpose purpose)
 {
+	int (*init_fs_context)(struct fs_context *, struct dentry *);
 	struct fs_context *fc;
 	int ret = -ENOMEM;
 
@@ -246,15 +248,6 @@ struct fs_context *vfs_new_fs_context(struct file_system_type *fs_type,
 	if (!fc)
 		return ERR_PTR(-ENOMEM);
 
-	if (!fs_type->init_fs_context) {
-		fc->fs_private = kzalloc(sizeof(struct legacy_fs_context),
-					 GFP_KERNEL);
-		if (!fc->fs_private)
-			goto err_fc;
-
-		fc->ops = &legacy_fs_context_ops;
-	}
-
 	fc->purpose	= purpose;
 	fc->sb_flags	= sb_flags;
 	fc->fs_type	= get_filesystem(fs_type);
@@ -285,11 +278,13 @@ struct fs_context *vfs_new_fs_context(struct file_system_type *fs_type,
 
 
 	/* TODO: Make all filesystems support this unconditionally */
-	if (fc->fs_type->init_fs_context) {
-		ret = fc->fs_type->init_fs_context(fc, reference);
-		if (ret < 0)
-			goto err_fc;
-	}
+	init_fs_context = fc->fs_type->init_fs_context;
+	if (!init_fs_context)
+		init_fs_context = legacy_init_fs_context;
+
+	ret = (*init_fs_context)(fc, reference);
+	if (ret < 0)
+		goto err_fc;
 
 	/* Do the security check last because ->init_fs_context may change the
 	 * namespace subscriptions.
@@ -499,19 +494,21 @@ static void legacy_fs_context_free(struct fs_context *fc)
 {
 	struct legacy_fs_context *ctx = fc->fs_private;
 
-	free_secdata(ctx->secdata);
-	switch (ctx->param_type) {
-	case LEGACY_FS_UNSET_PARAMS:
-	case LEGACY_FS_NO_PARAMS:
-		break;
-	case LEGACY_FS_MAGIC_PARAMS:
-		break; /* ctx->data is a weird pointer */
-	default:
-		kfree(ctx->legacy_data);
-		break;
-	}
+	if (ctx) {
+		free_secdata(ctx->secdata);
+		switch (ctx->param_type) {
+		case LEGACY_FS_UNSET_PARAMS:
+		case LEGACY_FS_NO_PARAMS:
+			break;
+		case LEGACY_FS_MAGIC_PARAMS:
+			break; /* ctx->data is a weird pointer */
+		default:
+			kfree(ctx->legacy_data);
+			break;
+		}
 
-	kfree(ctx);
+		kfree(ctx);
+	}
 }
 
 /*
@@ -707,3 +704,18 @@ static const struct fs_context_operations legacy_fs_context_ops = {
 	.validate		= legacy_validate,
 	.get_tree		= legacy_get_tree,
 };
+
+/*
+ * Initialise a legacy context for a filesystem that doesn't support
+ * fs_context.
+ */
+static int legacy_init_fs_context(struct fs_context *fc, struct dentry *dentry)
+{
+
+	fc->fs_private = kzalloc(sizeof(struct legacy_fs_context), GFP_KERNEL);
+	if (!fc->fs_private)
+		return -ENOMEM;
+
+	fc->ops = &legacy_fs_context_ops;
+	return 0;
+}

  parent reply	other threads:[~2018-07-10  8:02 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-08 21:01 [PATCH vfs/for-next 00/18] fs_context fixes Eric Biggers
2018-07-08 21:01 ` [PATCH 01/18] sysfs: check return value of kernfs_get_tree() Eric Biggers
2018-07-08 21:01 ` [PATCH 02/18] fs_context: fix shrinker leak in sget_fc() Eric Biggers
2018-07-08 21:01 ` [PATCH 03/18] fs_context: fix detecting full log buffer Eric Biggers
2018-07-08 21:01 ` [PATCH 04/18] fs_context: fix fs_context leak in simple_pin_fs() Eric Biggers
2018-07-08 21:01 ` [PATCH 05/18] fs_context: fix mount option blacklist Eric Biggers
2018-07-08 21:01 ` [PATCH 06/18] fs_context: fix memory leak with 's' (source) command Eric Biggers
2018-07-08 21:01 ` [PATCH 07/18] fs_context: fix double free of legacy_fs_context data Eric Biggers
2018-07-08 21:01 ` [PATCH 08/18] fsmount: pass up error code from dentry_open() Eric Biggers
2018-07-08 21:01 ` [PATCH 09/18] fsmount: fix handling FSMOUNT_CLOEXEC Eric Biggers
2018-07-08 21:01 ` [PATCH 10/18] fsmount: fix bypassing SB_MANDLOCK permission check Eric Biggers
2018-07-08 21:01 ` [PATCH 11/18] fspick: fix path leak Eric Biggers
2018-07-08 21:01 ` [PATCH 12/18] fspick: add missing permission check Eric Biggers
2018-07-08 21:01 ` [PATCH 13/18] fsmount: removed unused variable 'inode' Eric Biggers
2018-07-08 21:01 ` [PATCH 14/18] fsopen,fspick: factor out log allocation Eric Biggers
2018-07-08 21:01 ` [PATCH 15/18] fsopen,fspick: rename fsopen_create_fd() to fscontext_create_fd() Eric Biggers
2018-07-08 21:01 ` [PATCH 16/18] fs_context: de-obfuscate control flow in fscontext_read() Eric Biggers
2018-07-08 21:01 ` [PATCH 17/18] fs_context: de-obfuscate command validation Eric Biggers
2018-07-08 21:01 ` [PATCH 18/18] fs_context: fix fscontext_write() comment Eric Biggers
2018-07-08 23:46 ` [PATCH vfs/for-next 00/18] fs_context fixes Eric Biggers
2018-07-09  9:32 ` [PATCH 03/18] fs_context: fix detecting full log buffer David Howells
2018-07-09  9:35 ` David Howells
2018-07-09 12:31 ` [PATCH 07/18] fs_context: fix double free of legacy_fs_context data David Howells
2018-07-10  1:17   ` Eric Biggers
2018-07-10  1:25     ` Eric Biggers
2018-07-10  8:02   ` David Howells [this message]
2018-07-09 15:31 ` [PATCH vfs/for-next 00/18] fs_context fixes David Howells
2018-07-09 15:56   ` Al Viro
2018-07-09 16:28   ` David Howells
2018-07-09 21:57   ` David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=25103.1531209724@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=ebiggers3@gmail.com \
    --cc=ebiggers@google.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).