Skip to content

Commit 866eef4

Browse files
author
Andreas Gruenbacher
committed
gfs2: Add trusted xattr support
Add support for an additional filesystem version (sb_fs_format = 1802). When a filesystem with the new version is mounted, the filesystem supports "trusted.*" xattrs. In addition, version 1802 filesystems implement a form of forward compatibility for xattrs: when xattrs with an unknown prefix (ea_type) are found on a version 1802 filesystem, those attributes are not shown by listxattr, and they are not accessible by getxattr, setxattr, or removexattr. This mechanism might turn out to be what we need in the future, but if not, we can always bump the filesystem version and break compatibility instead. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Andrew Price <anprice@redhat.com>
1 parent 47b7ec1 commit 866eef4

4 files changed

Lines changed: 63 additions & 8 deletions

File tree

fs/gfs2/ops_fstype.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,19 @@ static int init_sb(struct gfs2_sbd *sdp, int silent)
489489
goto out;
490490
}
491491

492+
switch(sdp->sd_sb.sb_fs_format) {
493+
case GFS2_FS_FORMAT_MAX:
494+
sb->s_xattr = gfs2_xattr_handlers_max;
495+
break;
496+
497+
case GFS2_FS_FORMAT_MIN:
498+
sb->s_xattr = gfs2_xattr_handlers_min;
499+
break;
500+
501+
default:
502+
BUG();
503+
}
504+
492505
/* Set up the buffer cache and SB for real */
493506
if (sdp->sd_sb.sb_bsize < bdev_logical_block_size(sb->s_bdev)) {
494507
ret = -EINVAL;
@@ -1110,7 +1123,6 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
11101123
sb->s_op = &gfs2_super_ops;
11111124
sb->s_d_op = &gfs2_dops;
11121125
sb->s_export_op = &gfs2_export_ops;
1113-
sb->s_xattr = gfs2_xattr_handlers;
11141126
sb->s_qcop = &gfs2_quotactl_ops;
11151127
sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
11161128
sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;

fs/gfs2/super.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ extern struct file_system_type gfs2meta_fs_type;
5858
extern const struct export_operations gfs2_export_ops;
5959
extern const struct super_operations gfs2_super_ops;
6060
extern const struct dentry_operations gfs2_dops;
61-
extern const struct xattr_handler *gfs2_xattr_handlers[];
61+
62+
extern const struct xattr_handler *gfs2_xattr_handlers_max[];
63+
extern const struct xattr_handler **gfs2_xattr_handlers_min;
6264

6365
#endif /* __SUPER_DOT_H__ */
6466

fs/gfs2/xattr.c

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,28 @@ static int ea_check_size(struct gfs2_sbd *sdp, unsigned int nsize, size_t dsize)
7070
return 0;
7171
}
7272

73+
static bool gfs2_eatype_valid(struct gfs2_sbd *sdp, u8 type)
74+
{
75+
switch(sdp->sd_sb.sb_fs_format) {
76+
case GFS2_FS_FORMAT_MAX:
77+
return true;
78+
79+
case GFS2_FS_FORMAT_MIN:
80+
return type <= GFS2_EATYPE_SECURITY;
81+
82+
default:
83+
return false;
84+
}
85+
}
86+
7387
typedef int (*ea_call_t) (struct gfs2_inode *ip, struct buffer_head *bh,
7488
struct gfs2_ea_header *ea,
7589
struct gfs2_ea_header *prev, void *private);
7690

7791
static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
7892
ea_call_t ea_call, void *data)
7993
{
94+
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
8095
struct gfs2_ea_header *ea, *prev = NULL;
8196
int error = 0;
8297

@@ -89,9 +104,8 @@ static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
89104
if (!(bh->b_data <= (char *)ea && (char *)GFS2_EA2NEXT(ea) <=
90105
bh->b_data + bh->b_size))
91106
goto fail;
92-
if (!GFS2_EATYPE_VALID(ea->ea_type))
107+
if (!gfs2_eatype_valid(sdp, ea->ea_type))
93108
goto fail;
94-
95109
error = ea_call(ip, bh, ea, prev, data);
96110
if (error)
97111
return error;
@@ -344,6 +358,7 @@ static int ea_list_i(struct gfs2_inode *ip, struct buffer_head *bh,
344358
struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
345359
void *private)
346360
{
361+
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
347362
struct ea_list *ei = private;
348363
struct gfs2_ea_request *er = ei->ei_er;
349364
unsigned int ea_size;
@@ -353,6 +368,8 @@ static int ea_list_i(struct gfs2_inode *ip, struct buffer_head *bh,
353368
if (ea->ea_type == GFS2_EATYPE_UNUSED)
354369
return 0;
355370

371+
BUG_ON(ea->ea_type > GFS2_EATYPE_SECURITY &&
372+
sdp->sd_sb.sb_fs_format == GFS2_FS_FORMAT_MIN);
356373
switch (ea->ea_type) {
357374
case GFS2_EATYPE_USR:
358375
prefix = "user.";
@@ -366,8 +383,12 @@ static int ea_list_i(struct gfs2_inode *ip, struct buffer_head *bh,
366383
prefix = "security.";
367384
l = 9;
368385
break;
386+
case GFS2_EATYPE_TRUSTED:
387+
prefix = "trusted.";
388+
l = 8;
389+
break;
369390
default:
370-
BUG();
391+
return 0;
371392
}
372393

373394
ea_size = l + ea->ea_name_len + 1;
@@ -1463,11 +1484,30 @@ static const struct xattr_handler gfs2_xattr_security_handler = {
14631484
.set = gfs2_xattr_set,
14641485
};
14651486

1466-
const struct xattr_handler *gfs2_xattr_handlers[] = {
1487+
static bool
1488+
gfs2_xattr_trusted_list(struct dentry *dentry)
1489+
{
1490+
return capable(CAP_SYS_ADMIN);
1491+
}
1492+
1493+
static const struct xattr_handler gfs2_xattr_trusted_handler = {
1494+
.prefix = XATTR_TRUSTED_PREFIX,
1495+
.flags = GFS2_EATYPE_TRUSTED,
1496+
.list = gfs2_xattr_trusted_list,
1497+
.get = gfs2_xattr_get,
1498+
.set = gfs2_xattr_set,
1499+
};
1500+
1501+
const struct xattr_handler *gfs2_xattr_handlers_max[] = {
1502+
/* GFS2_FS_FORMAT_MAX */
1503+
&gfs2_xattr_trusted_handler,
1504+
1505+
/* GFS2_FS_FORMAT_MIN */
14671506
&gfs2_xattr_user_handler,
14681507
&gfs2_xattr_security_handler,
14691508
&posix_acl_access_xattr_handler,
14701509
&posix_acl_default_xattr_handler,
14711510
NULL,
14721511
};
14731512

1513+
const struct xattr_handler **gfs2_xattr_handlers_min = gfs2_xattr_handlers_max + 1;

include/uapi/linux/gfs2_ondisk.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
#define GFS2_FORMAT_DE 1200
4848
#define GFS2_FORMAT_QU 1500
4949
/* These are part of the superblock */
50-
#define GFS2_FORMAT_FS 1801
50+
#define GFS2_FORMAT_FS 1802
5151
#define GFS2_FORMAT_MULTI 1900
5252

5353
/*
@@ -389,8 +389,9 @@ struct gfs2_leaf {
389389
#define GFS2_EATYPE_USR 1
390390
#define GFS2_EATYPE_SYS 2
391391
#define GFS2_EATYPE_SECURITY 3
392+
#define GFS2_EATYPE_TRUSTED 4
392393

393-
#define GFS2_EATYPE_LAST 3
394+
#define GFS2_EATYPE_LAST 4
394395
#define GFS2_EATYPE_VALID(x) ((x) <= GFS2_EATYPE_LAST)
395396

396397
#define GFS2_EAFLAG_LAST 0x01 /* last ea in block */

0 commit comments

Comments
 (0)