Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27591187 authored by Brian Norris's avatar Brian Norris Committed by Greg Kroah-Hartman
Browse files

tracefs: Only clobber mode/uid/gid on remount if asked

commit 47311db8e8f33011d90dee76b39c8886120cdda4 upstream.

Users may have explicitly configured their tracefs permissions; we
shouldn't overwrite those just because a second mount appeared.

Only clobber if the options were provided at mount time.

Note: the previous behavior was especially surprising in the presence of
automounted /sys/kernel/debug/tracing/.

Existing behavior:

  ## Pre-existing status: tracefs is 0755.
  # stat -c '%A' /sys/kernel/tracing/
  drwxr-xr-x

  ## (Re)trigger the automount.
  # umount /sys/kernel/debug/tracing
  # stat -c '%A' /sys/kernel/debug/tracing/.
  drwx------

  ## Unexpected: the automount changed mode for other mount instances.
  # stat -c '%A' /sys/kernel/tracing/
  drwx------

New behavior (after this change):

  ## Pre-existing status: tracefs is 0755.
  # stat -c '%A' /sys/kernel/tracing/
  drwxr-xr-x

  ## (Re)trigger the automount.
  # umount /sys/kernel/debug/tracing
  # stat -c '%A' /sys/kernel/debug/tracing/.
  drwxr-xr-x

  ## Expected: the automount does not change other mount instances.
  # stat -c '%A' /sys/kernel/tracing/
  drwxr-xr-x

Link: https://lkml.kernel.org/r/20220826174353.2.Iab6e5ea57963d6deca5311b27fb7226790d44406@changeid



Cc: stable@vger.kernel.org
Fixes: 4282d606 ("tracefs: Add new tracefs file system")
Signed-off-by: default avatarBrian Norris <briannorris@chromium.org>
Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 30fdd637
Loading
Loading
Loading
Loading
+23 −8
Original line number Diff line number Diff line
@@ -142,6 +142,8 @@ struct tracefs_mount_opts {
	kuid_t uid;
	kgid_t gid;
	umode_t mode;
	/* Opt_* bitfield. */
	unsigned int opts;
};

enum {
@@ -242,6 +244,7 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)
	kgid_t gid;
	char *p;

	opts->opts = 0;
	opts->mode = TRACEFS_DEFAULT_MODE;

	while ((p = strsep(&data, ",")) != NULL) {
@@ -276,24 +279,36 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)
		 * but traditionally tracefs has ignored all mount options
		 */
		}

		opts->opts |= BIT(token);
	}

	return 0;
}

static int tracefs_apply_options(struct super_block *sb)
static int tracefs_apply_options(struct super_block *sb, bool remount)
{
	struct tracefs_fs_info *fsi = sb->s_fs_info;
	struct inode *inode = sb->s_root->d_inode;
	struct tracefs_mount_opts *opts = &fsi->mount_opts;

	/*
	 * On remount, only reset mode/uid/gid if they were provided as mount
	 * options.
	 */

	if (!remount || opts->opts & BIT(Opt_mode)) {
		inode->i_mode &= ~S_IALLUGO;
		inode->i_mode |= opts->mode;
	}

	if (!remount || opts->opts & BIT(Opt_uid))
		inode->i_uid = opts->uid;

	if (!remount || opts->opts & BIT(Opt_gid)) {
		/* Set all the group ids to the mount option */
		set_gid(sb->s_root, opts->gid);
	}

	return 0;
}
@@ -308,7 +323,7 @@ static int tracefs_remount(struct super_block *sb, int *flags, char *data)
	if (err)
		goto fail;

	tracefs_apply_options(sb);
	tracefs_apply_options(sb, true);

fail:
	return err;
@@ -360,7 +375,7 @@ static int trace_fill_super(struct super_block *sb, void *data, int silent)

	sb->s_op = &tracefs_super_operations;

	tracefs_apply_options(sb);
	tracefs_apply_options(sb, false);

	return 0;