mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-01 10:42:11 +00:00
tracefs: Only clobber mode/uid/gid on remount if asked
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: 4282d60689
("tracefs: Add new tracefs file system")
Signed-off-by: Brian Norris <briannorris@chromium.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
This commit is contained in:
parent
1efda38d6f
commit
47311db8e8
@ -141,6 +141,8 @@ struct tracefs_mount_opts {
|
||||
kuid_t uid;
|
||||
kgid_t gid;
|
||||
umode_t mode;
|
||||
/* Opt_* bitfield. */
|
||||
unsigned int opts;
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -241,6 +243,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) {
|
||||
@ -275,24 +278,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 = d_inode(sb->s_root);
|
||||
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.
|
||||
*/
|
||||
|
||||
inode->i_uid = opts->uid;
|
||||
if (!remount || opts->opts & BIT(Opt_mode)) {
|
||||
inode->i_mode &= ~S_IALLUGO;
|
||||
inode->i_mode |= opts->mode;
|
||||
}
|
||||
|
||||
/* Set all the group ids to the mount option */
|
||||
set_gid(sb->s_root, opts->gid);
|
||||
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;
|
||||
}
|
||||
@ -307,7 +322,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;
|
||||
@ -359,7 +374,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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user