Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fuse: Ensure posix acls are translated outside of init_user_ns

Ensure the translation happens by failing to read or write
posix acls when the filesystem has not indicated it supports
posix acls.

This ensures that modern cached posix acl support is available
and used when dealing with posix acls. This is important
because only that path has the code to convernt the uids and
gids in posix acls into the user namespace of a fuse filesystem.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>

authored by

Eric W. Biederman and committed by
Miklos Szeredi
e45b2546 5ba24197

+51
+1
fs/fuse/fuse_i.h
··· 985 985 int fuse_removexattr(struct inode *inode, const char *name); 986 986 extern const struct xattr_handler *fuse_xattr_handlers[]; 987 987 extern const struct xattr_handler *fuse_acl_xattr_handlers[]; 988 + extern const struct xattr_handler *fuse_no_acl_xattr_handlers[]; 988 989 989 990 struct posix_acl; 990 991 struct posix_acl *fuse_get_acl(struct inode *inode, int type);
+7
fs/fuse/inode.c
··· 1100 1100 file->f_cred->user_ns != sb->s_user_ns) 1101 1101 goto err_fput; 1102 1102 1103 + /* 1104 + * If we are not in the initial user namespace posix 1105 + * acls must be translated. 1106 + */ 1107 + if (sb->s_user_ns != &init_user_ns) 1108 + sb->s_xattr = fuse_no_acl_xattr_handlers; 1109 + 1103 1110 fc = kmalloc(sizeof(*fc), GFP_KERNEL); 1104 1111 err = -ENOMEM; 1105 1112 if (!fc)
+43
fs/fuse/xattr.c
··· 192 192 return fuse_setxattr(inode, name, value, size, flags); 193 193 } 194 194 195 + static bool no_xattr_list(struct dentry *dentry) 196 + { 197 + return false; 198 + } 199 + 200 + static int no_xattr_get(const struct xattr_handler *handler, 201 + struct dentry *dentry, struct inode *inode, 202 + const char *name, void *value, size_t size) 203 + { 204 + return -EOPNOTSUPP; 205 + } 206 + 207 + static int no_xattr_set(const struct xattr_handler *handler, 208 + struct dentry *dentry, struct inode *nodee, 209 + const char *name, const void *value, 210 + size_t size, int flags) 211 + { 212 + return -EOPNOTSUPP; 213 + } 214 + 195 215 static const struct xattr_handler fuse_xattr_handler = { 196 216 .prefix = "", 197 217 .get = fuse_xattr_get, ··· 226 206 const struct xattr_handler *fuse_acl_xattr_handlers[] = { 227 207 &posix_acl_access_xattr_handler, 228 208 &posix_acl_default_xattr_handler, 209 + &fuse_xattr_handler, 210 + NULL 211 + }; 212 + 213 + static const struct xattr_handler fuse_no_acl_access_xattr_handler = { 214 + .name = XATTR_NAME_POSIX_ACL_ACCESS, 215 + .flags = ACL_TYPE_ACCESS, 216 + .list = no_xattr_list, 217 + .get = no_xattr_get, 218 + .set = no_xattr_set, 219 + }; 220 + 221 + static const struct xattr_handler fuse_no_acl_default_xattr_handler = { 222 + .name = XATTR_NAME_POSIX_ACL_DEFAULT, 223 + .flags = ACL_TYPE_ACCESS, 224 + .list = no_xattr_list, 225 + .get = no_xattr_get, 226 + .set = no_xattr_set, 227 + }; 228 + 229 + const struct xattr_handler *fuse_no_acl_xattr_handlers[] = { 230 + &fuse_no_acl_access_xattr_handler, 231 + &fuse_no_acl_default_xattr_handler, 229 232 &fuse_xattr_handler, 230 233 NULL 231 234 };