Skip to content

Commit b8fc1bd

Browse files
committed
Merge tag 'vfs-6.11.mount.api' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs mount API updates from Christian Brauner: - Add a generic helper to parse uid and gid mount options. Currently we open-code the same logic in various filesystems which is error prone, especially since the verification of uid and gid mount options is a sensitive operation in the face of idmappings. Add a generic helper and convert all filesystems over to it. Make sure that filesystems that are mountable in unprivileged containers verify that the specified uid and gid can be represented in the owning namespace of the filesystem. - Convert hostfs to the new mount api. * tag 'vfs-6.11.mount.api' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: fuse: Convert to new uid/gid option parsing helpers fuse: verify {g,u}id mount options correctly fat: Convert to new uid/gid option parsing helpers fat: Convert to new mount api fat: move debug into fat_mount_options vboxsf: Convert to new uid/gid option parsing helpers tracefs: Convert to new uid/gid option parsing helpers smb: client: Convert to new uid/gid option parsing helpers tmpfs: Convert to new uid/gid option parsing helpers ntfs3: Convert to new uid/gid option parsing helpers isofs: Convert to new uid/gid option parsing helpers hugetlbfs: Convert to new uid/gid option parsing helpers ext4: Convert to new uid/gid option parsing helpers exfat: Convert to new uid/gid option parsing helpers efivarfs: Convert to new uid/gid option parsing helpers debugfs: Convert to new uid/gid option parsing helpers autofs: Convert to new uid/gid option parsing helpers fs_parse: add uid & gid option option parsing helpers hostfs: Add const qualifier to host_root in hostfs_fill_super() hostfs: convert hostfs to use the new mount API
2 parents 4a051e4 + eea6a83 commit b8fc1bd

File tree

21 files changed

+594
-527
lines changed

21 files changed

+594
-527
lines changed

Documentation/filesystems/mount_api.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,8 @@ The members are as follows:
645645
fs_param_is_blockdev Blockdev path * Needs lookup
646646
fs_param_is_path Path * Needs lookup
647647
fs_param_is_fd File descriptor result->int_32
648+
fs_param_is_uid User ID (u32) result->uid
649+
fs_param_is_gid Group ID (u32) result->gid
648650
======================= ======================= =====================
649651

650652
Note that if the value is of fs_param_is_bool type, fs_parse() will try
@@ -678,6 +680,8 @@ The members are as follows:
678680
fsparam_bdev() fs_param_is_blockdev
679681
fsparam_path() fs_param_is_path
680682
fsparam_fd() fs_param_is_fd
683+
fsparam_uid() fs_param_is_uid
684+
fsparam_gid() fs_param_is_gid
681685
======================= ===============================================
682686

683687
all of which take two arguments, name string and option number - for
@@ -784,8 +788,9 @@ process the parameters it is given.
784788
option number (which it returns).
785789

786790
If successful, and if the parameter type indicates the result is a
787-
boolean, integer or enum type, the value is converted by this function and
788-
the result stored in result->{boolean,int_32,uint_32,uint_64}.
791+
boolean, integer, enum, uid, or gid type, the value is converted by this
792+
function and the result stored in
793+
result->{boolean,int_32,uint_32,uint_64,uid,gid}.
789794

790795
If a match isn't initially made, the key is prefixed with "no" and no
791796
value is present then an attempt will be made to look up the key with the

fs/autofs/inode.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,15 @@ enum {
126126
const struct fs_parameter_spec autofs_param_specs[] = {
127127
fsparam_flag ("direct", Opt_direct),
128128
fsparam_fd ("fd", Opt_fd),
129-
fsparam_u32 ("gid", Opt_gid),
129+
fsparam_gid ("gid", Opt_gid),
130130
fsparam_flag ("ignore", Opt_ignore),
131131
fsparam_flag ("indirect", Opt_indirect),
132132
fsparam_u32 ("maxproto", Opt_maxproto),
133133
fsparam_u32 ("minproto", Opt_minproto),
134134
fsparam_flag ("offset", Opt_offset),
135135
fsparam_u32 ("pgrp", Opt_pgrp),
136136
fsparam_flag ("strictexpire", Opt_strictexpire),
137-
fsparam_u32 ("uid", Opt_uid),
137+
fsparam_uid ("uid", Opt_uid),
138138
{}
139139
};
140140

@@ -193,8 +193,6 @@ static int autofs_parse_param(struct fs_context *fc, struct fs_parameter *param)
193193
struct autofs_fs_context *ctx = fc->fs_private;
194194
struct autofs_sb_info *sbi = fc->s_fs_info;
195195
struct fs_parse_result result;
196-
kuid_t uid;
197-
kgid_t gid;
198196
int opt;
199197

200198
opt = fs_parse(fc, autofs_param_specs, param, &result);
@@ -205,16 +203,10 @@ static int autofs_parse_param(struct fs_context *fc, struct fs_parameter *param)
205203
case Opt_fd:
206204
return autofs_parse_fd(fc, sbi, param, &result);
207205
case Opt_uid:
208-
uid = make_kuid(current_user_ns(), result.uint_32);
209-
if (!uid_valid(uid))
210-
return invalfc(fc, "Invalid uid");
211-
ctx->uid = uid;
206+
ctx->uid = result.uid;
212207
break;
213208
case Opt_gid:
214-
gid = make_kgid(current_user_ns(), result.uint_32);
215-
if (!gid_valid(gid))
216-
return invalfc(fc, "Invalid gid");
217-
ctx->gid = gid;
209+
ctx->gid = result.gid;
218210
break;
219211
case Opt_pgrp:
220212
ctx->pgrp = result.uint_32;

fs/debugfs/inode.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,16 @@ enum {
9292
};
9393

9494
static const struct fs_parameter_spec debugfs_param_specs[] = {
95-
fsparam_u32 ("gid", Opt_gid),
95+
fsparam_gid ("gid", Opt_gid),
9696
fsparam_u32oct ("mode", Opt_mode),
97-
fsparam_u32 ("uid", Opt_uid),
97+
fsparam_uid ("uid", Opt_uid),
9898
{}
9999
};
100100

101101
static int debugfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
102102
{
103103
struct debugfs_fs_info *opts = fc->s_fs_info;
104104
struct fs_parse_result result;
105-
kuid_t uid;
106-
kgid_t gid;
107105
int opt;
108106

109107
opt = fs_parse(fc, debugfs_param_specs, param, &result);
@@ -120,16 +118,10 @@ static int debugfs_parse_param(struct fs_context *fc, struct fs_parameter *param
120118

121119
switch (opt) {
122120
case Opt_uid:
123-
uid = make_kuid(current_user_ns(), result.uint_32);
124-
if (!uid_valid(uid))
125-
return invalf(fc, "Unknown uid");
126-
opts->uid = uid;
121+
opts->uid = result.uid;
127122
break;
128123
case Opt_gid:
129-
gid = make_kgid(current_user_ns(), result.uint_32);
130-
if (!gid_valid(gid))
131-
return invalf(fc, "Unknown gid");
132-
opts->gid = gid;
124+
opts->gid = result.gid;
133125
break;
134126
case Opt_mode:
135127
opts->mode = result.uint_32 & S_IALLUGO;

fs/efivarfs/super.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,8 @@ enum {
275275
};
276276

277277
static const struct fs_parameter_spec efivarfs_parameters[] = {
278-
fsparam_u32("uid", Opt_uid),
279-
fsparam_u32("gid", Opt_gid),
278+
fsparam_uid("uid", Opt_uid),
279+
fsparam_gid("gid", Opt_gid),
280280
{},
281281
};
282282

@@ -293,14 +293,10 @@ static int efivarfs_parse_param(struct fs_context *fc, struct fs_parameter *para
293293

294294
switch (opt) {
295295
case Opt_uid:
296-
opts->uid = make_kuid(current_user_ns(), result.uint_32);
297-
if (!uid_valid(opts->uid))
298-
return -EINVAL;
296+
opts->uid = result.uid;
299297
break;
300298
case Opt_gid:
301-
opts->gid = make_kgid(current_user_ns(), result.uint_32);
302-
if (!gid_valid(opts->gid))
303-
return -EINVAL;
299+
opts->gid = result.gid;
304300
break;
305301
default:
306302
return -EINVAL;

fs/exfat/super.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ static const struct constant_table exfat_param_enums[] = {
225225
};
226226

227227
static const struct fs_parameter_spec exfat_parameters[] = {
228-
fsparam_u32("uid", Opt_uid),
229-
fsparam_u32("gid", Opt_gid),
228+
fsparam_uid("uid", Opt_uid),
229+
fsparam_gid("gid", Opt_gid),
230230
fsparam_u32oct("umask", Opt_umask),
231231
fsparam_u32oct("dmask", Opt_dmask),
232232
fsparam_u32oct("fmask", Opt_fmask),
@@ -262,10 +262,10 @@ static int exfat_parse_param(struct fs_context *fc, struct fs_parameter *param)
262262

263263
switch (opt) {
264264
case Opt_uid:
265-
opts->fs_uid = make_kuid(current_user_ns(), result.uint_32);
265+
opts->fs_uid = result.uid;
266266
break;
267267
case Opt_gid:
268-
opts->fs_gid = make_kgid(current_user_ns(), result.uint_32);
268+
opts->fs_gid = result.gid;
269269
break;
270270
case Opt_umask:
271271
opts->fs_fmask = result.uint_32;

fs/ext4/super.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,8 +1721,8 @@ static const struct fs_parameter_spec ext4_param_specs[] = {
17211721
fsparam_flag ("bsdgroups", Opt_grpid),
17221722
fsparam_flag ("nogrpid", Opt_nogrpid),
17231723
fsparam_flag ("sysvgroups", Opt_nogrpid),
1724-
fsparam_u32 ("resgid", Opt_resgid),
1725-
fsparam_u32 ("resuid", Opt_resuid),
1724+
fsparam_gid ("resgid", Opt_resgid),
1725+
fsparam_uid ("resuid", Opt_resuid),
17261726
fsparam_u32 ("sb", Opt_sb),
17271727
fsparam_enum ("errors", Opt_errors, ext4_param_errors),
17281728
fsparam_flag ("nouid32", Opt_nouid32),
@@ -2127,8 +2127,6 @@ static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param)
21272127
struct fs_parse_result result;
21282128
const struct mount_opts *m;
21292129
int is_remount;
2130-
kuid_t uid;
2131-
kgid_t gid;
21322130
int token;
21332131

21342132
token = fs_parse(fc, ext4_param_specs, param, &result);
@@ -2270,23 +2268,11 @@ static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param)
22702268
ctx->spec |= EXT4_SPEC_s_stripe;
22712269
return 0;
22722270
case Opt_resuid:
2273-
uid = make_kuid(current_user_ns(), result.uint_32);
2274-
if (!uid_valid(uid)) {
2275-
ext4_msg(NULL, KERN_ERR, "Invalid uid value %d",
2276-
result.uint_32);
2277-
return -EINVAL;
2278-
}
2279-
ctx->s_resuid = uid;
2271+
ctx->s_resuid = result.uid;
22802272
ctx->spec |= EXT4_SPEC_s_resuid;
22812273
return 0;
22822274
case Opt_resgid:
2283-
gid = make_kgid(current_user_ns(), result.uint_32);
2284-
if (!gid_valid(gid)) {
2285-
ext4_msg(NULL, KERN_ERR, "Invalid gid value %d",
2286-
result.uint_32);
2287-
return -EINVAL;
2288-
}
2289-
ctx->s_resgid = gid;
2275+
ctx->s_resgid = result.gid;
22902276
ctx->spec |= EXT4_SPEC_s_resgid;
22912277
return 0;
22922278
case Opt_journal_dev:

fs/fat/fat.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <linux/hash.h>
88
#include <linux/ratelimit.h>
99
#include <linux/msdos_fs.h>
10+
#include <linux/fs_context.h>
11+
#include <linux/fs_parser.h>
1012

1113
/*
1214
* vfat shortname flags
@@ -51,7 +53,8 @@ struct fat_mount_options {
5153
tz_set:1, /* Filesystem timestamps' offset set */
5254
rodir:1, /* allow ATTR_RO for directory */
5355
discard:1, /* Issue discard requests on deletions */
54-
dos1xfloppy:1; /* Assume default BPB for DOS 1.x floppies */
56+
dos1xfloppy:1, /* Assume default BPB for DOS 1.x floppies */
57+
debug:1; /* Not currently used */
5558
};
5659

5760
#define FAT_HASH_BITS 8
@@ -415,12 +418,21 @@ extern struct inode *fat_iget(struct super_block *sb, loff_t i_pos);
415418
extern struct inode *fat_build_inode(struct super_block *sb,
416419
struct msdos_dir_entry *de, loff_t i_pos);
417420
extern int fat_sync_inode(struct inode *inode);
418-
extern int fat_fill_super(struct super_block *sb, void *data, int silent,
419-
int isvfat, void (*setup)(struct super_block *));
421+
extern int fat_fill_super(struct super_block *sb, struct fs_context *fc,
422+
void (*setup)(struct super_block *));
420423
extern int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de);
421424

422425
extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
423426
struct inode *i2);
427+
428+
extern const struct fs_parameter_spec fat_param_spec[];
429+
int fat_init_fs_context(struct fs_context *fc, bool is_vfat);
430+
void fat_free_fc(struct fs_context *fc);
431+
432+
int fat_parse_param(struct fs_context *fc, struct fs_parameter *param,
433+
bool is_vfat);
434+
int fat_reconfigure(struct fs_context *fc);
435+
424436
static inline unsigned long fat_dir_hash(int logstart)
425437
{
426438
return hash_32(logstart, FAT_HASH_BITS);

0 commit comments

Comments
 (0)