Skip to content

Commit b8de524

Browse files
computersforpeacegregkh
authored andcommitted
debugfs: Only clobber mode/uid/gid on remount if asked
Users may have explicitly configured their debugfs permissions; we shouldn't overwrite those just because a second mount appeared. Only clobber if the options were provided at mount time. Existing behavior: ## Pre-existing status: debugfs is 0755. # chmod 755 /sys/kernel/debug/ # stat -c '%A' /sys/kernel/debug/ drwxr-xr-x ## New mount sets kernel-default permissions: # mount -t debugfs none /mnt/foo # stat -c '%A' /mnt/foo drwx------ ## Unexpected: the original mount changed permissions: # stat -c '%A' /sys/kernel/debug drwx------ New behavior: ## Pre-existing status: debugfs is 0755. # chmod 755 /sys/kernel/debug/ # stat -c '%A' /sys/kernel/debug/ drwxr-xr-x ## New mount inherits existing permissions: # mount -t debugfs none /mnt/foo # stat -c '%A' /mnt/foo drwxr-xr-x ## Expected: old mount is unchanged: # stat -c '%A' /sys/kernel/debug drwxr-xr-x Full test cases are being submitted to LTP. Signed-off-by: Brian Norris <[email protected]> Link: https://lore.kernel.org/r/20220912163042.v3.1.Icbd40fce59f55ad74b80e5d435ea233579348a78@changeid Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 4abc996 commit b8de524

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

fs/debugfs/inode.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ struct debugfs_mount_opts {
8282
kuid_t uid;
8383
kgid_t gid;
8484
umode_t mode;
85+
/* Opt_* bitfield. */
86+
unsigned int opts;
8587
};
8688

8789
enum {
@@ -111,6 +113,7 @@ static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts)
111113
kgid_t gid;
112114
char *p;
113115

116+
opts->opts = 0;
114117
opts->mode = DEBUGFS_DEFAULT_MODE;
115118

116119
while ((p = strsep(&data, ",")) != NULL) {
@@ -145,24 +148,44 @@ static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts)
145148
* but traditionally debugfs has ignored all mount options
146149
*/
147150
}
151+
152+
opts->opts |= BIT(token);
148153
}
149154

150155
return 0;
151156
}
152157

153-
static int debugfs_apply_options(struct super_block *sb)
158+
static void _debugfs_apply_options(struct super_block *sb, bool remount)
154159
{
155160
struct debugfs_fs_info *fsi = sb->s_fs_info;
156161
struct inode *inode = d_inode(sb->s_root);
157162
struct debugfs_mount_opts *opts = &fsi->mount_opts;
158163

159-
inode->i_mode &= ~S_IALLUGO;
160-
inode->i_mode |= opts->mode;
164+
/*
165+
* On remount, only reset mode/uid/gid if they were provided as mount
166+
* options.
167+
*/
161168

162-
inode->i_uid = opts->uid;
163-
inode->i_gid = opts->gid;
169+
if (!remount || opts->opts & BIT(Opt_mode)) {
170+
inode->i_mode &= ~S_IALLUGO;
171+
inode->i_mode |= opts->mode;
172+
}
164173

165-
return 0;
174+
if (!remount || opts->opts & BIT(Opt_uid))
175+
inode->i_uid = opts->uid;
176+
177+
if (!remount || opts->opts & BIT(Opt_gid))
178+
inode->i_gid = opts->gid;
179+
}
180+
181+
static void debugfs_apply_options(struct super_block *sb)
182+
{
183+
_debugfs_apply_options(sb, false);
184+
}
185+
186+
static void debugfs_apply_options_remount(struct super_block *sb)
187+
{
188+
_debugfs_apply_options(sb, true);
166189
}
167190

168191
static int debugfs_remount(struct super_block *sb, int *flags, char *data)
@@ -175,7 +198,7 @@ static int debugfs_remount(struct super_block *sb, int *flags, char *data)
175198
if (err)
176199
goto fail;
177200

178-
debugfs_apply_options(sb);
201+
debugfs_apply_options_remount(sb);
179202

180203
fail:
181204
return err;

0 commit comments

Comments
 (0)