acl.c (6f84981772535e670e4e2df051a672af229b6694) | acl.c (facd61053cff100973921d4d45d47cf53c747ec6) |
---|---|
1/* 2 * FUSE: Filesystem in Userspace 3 * Copyright (C) 2016 Canonical Ltd. <seth.forshee@canonical.com> 4 * 5 * This program can be distributed under the terms of the GNU GPL. 6 * See the file COPYING. 7 */ 8 9#include "fuse_i.h" 10 11#include <linux/posix_acl.h> 12#include <linux/posix_acl_xattr.h> 13 | 1/* 2 * FUSE: Filesystem in Userspace 3 * Copyright (C) 2016 Canonical Ltd. <seth.forshee@canonical.com> 4 * 5 * This program can be distributed under the terms of the GNU GPL. 6 * See the file COPYING. 7 */ 8 9#include "fuse_i.h" 10 11#include <linux/posix_acl.h> 12#include <linux/posix_acl_xattr.h> 13 |
14struct posix_acl *fuse_get_acl(struct inode *inode, int type, bool rcu) | 14static struct posix_acl *__fuse_get_acl(struct fuse_conn *fc, 15 struct user_namespace *mnt_userns, 16 struct inode *inode, int type, bool rcu) |
15{ | 17{ |
16 struct fuse_conn *fc = get_fuse_conn(inode); | |
17 int size; 18 const char *name; 19 void *value = NULL; 20 struct posix_acl *acl; 21 22 if (rcu) 23 return ERR_PTR(-ECHILD); 24 25 if (fuse_is_bad(inode)) 26 return ERR_PTR(-EIO); 27 | 18 int size; 19 const char *name; 20 void *value = NULL; 21 struct posix_acl *acl; 22 23 if (rcu) 24 return ERR_PTR(-ECHILD); 25 26 if (fuse_is_bad(inode)) 27 return ERR_PTR(-EIO); 28 |
28 if (!fc->posix_acl || fc->no_getxattr) | 29 if (fc->no_getxattr) |
29 return NULL; 30 31 if (type == ACL_TYPE_ACCESS) 32 name = XATTR_NAME_POSIX_ACL_ACCESS; 33 else if (type == ACL_TYPE_DEFAULT) 34 name = XATTR_NAME_POSIX_ACL_DEFAULT; 35 else 36 return ERR_PTR(-EOPNOTSUPP); --- 11 unchanged lines hidden (view full) --- 48 acl = ERR_PTR(-E2BIG); 49 else 50 acl = ERR_PTR(size); 51 52 kfree(value); 53 return acl; 54} 55 | 30 return NULL; 31 32 if (type == ACL_TYPE_ACCESS) 33 name = XATTR_NAME_POSIX_ACL_ACCESS; 34 else if (type == ACL_TYPE_DEFAULT) 35 name = XATTR_NAME_POSIX_ACL_DEFAULT; 36 else 37 return ERR_PTR(-EOPNOTSUPP); --- 11 unchanged lines hidden (view full) --- 49 acl = ERR_PTR(-E2BIG); 50 else 51 acl = ERR_PTR(size); 52 53 kfree(value); 54 return acl; 55} 56 |
57static inline bool fuse_no_acl(const struct fuse_conn *fc, 58 const struct inode *inode) 59{ 60 /* 61 * Refuse interacting with POSIX ACLs for daemons that 62 * don't support FUSE_POSIX_ACL and are not mounted on 63 * the host to retain backwards compatibility. 64 */ 65 return !fc->posix_acl && (i_user_ns(inode) != &init_user_ns); 66} 67 68struct posix_acl *fuse_get_acl(struct user_namespace *mnt_userns, 69 struct dentry *dentry, int type) 70{ 71 struct inode *inode = d_inode(dentry); 72 struct fuse_conn *fc = get_fuse_conn(inode); 73 74 if (fuse_no_acl(fc, inode)) 75 return ERR_PTR(-EOPNOTSUPP); 76 77 return __fuse_get_acl(fc, mnt_userns, inode, type, false); 78} 79 80struct posix_acl *fuse_get_inode_acl(struct inode *inode, int type, bool rcu) 81{ 82 struct fuse_conn *fc = get_fuse_conn(inode); 83 84 /* 85 * FUSE daemons before FUSE_POSIX_ACL was introduced could get and set 86 * POSIX ACLs without them being used for permission checking by the 87 * vfs. Retain that behavior for backwards compatibility as there are 88 * filesystems that do all permission checking for acls in the daemon 89 * and not in the kernel. 90 */ 91 if (!fc->posix_acl) 92 return NULL; 93 94 return __fuse_get_acl(fc, &init_user_ns, inode, type, rcu); 95} 96 |
|
56int fuse_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry, 57 struct posix_acl *acl, int type) 58{ 59 struct inode *inode = d_inode(dentry); 60 struct fuse_conn *fc = get_fuse_conn(inode); 61 const char *name; 62 int ret; 63 64 if (fuse_is_bad(inode)) 65 return -EIO; 66 | 97int fuse_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry, 98 struct posix_acl *acl, int type) 99{ 100 struct inode *inode = d_inode(dentry); 101 struct fuse_conn *fc = get_fuse_conn(inode); 102 const char *name; 103 int ret; 104 105 if (fuse_is_bad(inode)) 106 return -EIO; 107 |
67 if (!fc->posix_acl || fc->no_setxattr) | 108 if (fc->no_setxattr || fuse_no_acl(fc, inode)) |
68 return -EOPNOTSUPP; 69 70 if (type == ACL_TYPE_ACCESS) 71 name = XATTR_NAME_POSIX_ACL_ACCESS; 72 else if (type == ACL_TYPE_DEFAULT) 73 name = XATTR_NAME_POSIX_ACL_DEFAULT; 74 else 75 return -EINVAL; --- 18 unchanged lines hidden (view full) --- 94 return -ENOMEM; 95 96 ret = posix_acl_to_xattr(fc->user_ns, acl, value, size); 97 if (ret < 0) { 98 kfree(value); 99 return ret; 100 } 101 | 109 return -EOPNOTSUPP; 110 111 if (type == ACL_TYPE_ACCESS) 112 name = XATTR_NAME_POSIX_ACL_ACCESS; 113 else if (type == ACL_TYPE_DEFAULT) 114 name = XATTR_NAME_POSIX_ACL_DEFAULT; 115 else 116 return -EINVAL; --- 18 unchanged lines hidden (view full) --- 135 return -ENOMEM; 136 137 ret = posix_acl_to_xattr(fc->user_ns, acl, value, size); 138 if (ret < 0) { 139 kfree(value); 140 return ret; 141 } 142 |
102 if (!vfsgid_in_group_p(i_gid_into_vfsgid(&init_user_ns, inode)) && | 143 /* 144 * Fuse daemons without FUSE_POSIX_ACL never changed the passed 145 * through POSIX ACLs. Such daemons don't expect setgid bits to 146 * be stripped. 147 */ 148 if (fc->posix_acl && 149 !vfsgid_in_group_p(i_gid_into_vfsgid(&init_user_ns, inode)) && |
103 !capable_wrt_inode_uidgid(&init_user_ns, inode, CAP_FSETID)) 104 extra_flags |= FUSE_SETXATTR_ACL_KILL_SGID; 105 106 ret = fuse_setxattr(inode, name, value, size, 0, extra_flags); 107 kfree(value); 108 } else { 109 ret = fuse_removexattr(inode, name); 110 } | 150 !capable_wrt_inode_uidgid(&init_user_ns, inode, CAP_FSETID)) 151 extra_flags |= FUSE_SETXATTR_ACL_KILL_SGID; 152 153 ret = fuse_setxattr(inode, name, value, size, 0, extra_flags); 154 kfree(value); 155 } else { 156 ret = fuse_removexattr(inode, name); 157 } |
111 forget_all_cached_acls(inode); 112 fuse_invalidate_attr(inode); | |
113 | 158 |
159 if (fc->posix_acl) { 160 /* 161 * Fuse daemons without FUSE_POSIX_ACL never cached POSIX ACLs 162 * and didn't invalidate attributes. Retain that behavior. 163 */ 164 forget_all_cached_acls(inode); 165 fuse_invalidate_attr(inode); 166 } 167 |
|
114 return ret; 115} | 168 return ret; 169} |