提交 b15e501f 编写于 作者: B Brian Norris 提交者: Yongqiang Liu

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

stable inclusion
from stable-v4.19.259
commit 27591187f95e6f67a40bba46f8306699d2ecbd81
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5V45M
CVE: NA

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

[ Upstream commit 47311db8 ]

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: NBrian Norris <briannorris@chromium.org>
Signed-off-by: NSteven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NLi Lingfeng <lilingfeng3@huawei.com>
Reviewed-by: NZhang Yi <yi.zhang@huawei.com>
Signed-off-by: NYongqiang Liu <liuyongqiang13@huawei.com>
上级 2265bd1b
...@@ -142,6 +142,8 @@ struct tracefs_mount_opts { ...@@ -142,6 +142,8 @@ struct tracefs_mount_opts {
kuid_t uid; kuid_t uid;
kgid_t gid; kgid_t gid;
umode_t mode; umode_t mode;
/* Opt_* bitfield. */
unsigned int opts;
}; };
enum { enum {
...@@ -171,6 +173,7 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) ...@@ -171,6 +173,7 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)
kgid_t gid; kgid_t gid;
char *p; char *p;
opts->opts = 0;
opts->mode = TRACEFS_DEFAULT_MODE; opts->mode = TRACEFS_DEFAULT_MODE;
while ((p = strsep(&data, ",")) != NULL) { while ((p = strsep(&data, ",")) != NULL) {
...@@ -205,22 +208,34 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) ...@@ -205,22 +208,34 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)
* but traditionally tracefs has ignored all mount options * but traditionally tracefs has ignored all mount options
*/ */
} }
opts->opts |= BIT(token);
} }
return 0; 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 tracefs_fs_info *fsi = sb->s_fs_info;
struct inode *inode = sb->s_root->d_inode; struct inode *inode = sb->s_root->d_inode;
struct tracefs_mount_opts *opts = &fsi->mount_opts; struct tracefs_mount_opts *opts = &fsi->mount_opts;
inode->i_mode &= ~S_IALLUGO; /*
inode->i_mode |= opts->mode; * 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;
inode->i_uid = opts->uid; if (!remount || opts->opts & BIT(Opt_gid))
inode->i_gid = opts->gid; inode->i_gid = opts->gid;
return 0; return 0;
} }
...@@ -235,7 +250,7 @@ static int tracefs_remount(struct super_block *sb, int *flags, char *data) ...@@ -235,7 +250,7 @@ static int tracefs_remount(struct super_block *sb, int *flags, char *data)
if (err) if (err)
goto fail; goto fail;
tracefs_apply_options(sb); tracefs_apply_options(sb, true);
fail: fail:
return err; return err;
...@@ -287,7 +302,7 @@ static int trace_fill_super(struct super_block *sb, void *data, int silent) ...@@ -287,7 +302,7 @@ static int trace_fill_super(struct super_block *sb, void *data, int silent)
sb->s_op = &tracefs_super_operations; sb->s_op = &tracefs_super_operations;
tracefs_apply_options(sb); tracefs_apply_options(sb, false);
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册