1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2008, Christoph Hellwig 4 * All Rights Reserved. 5 */ 6 #include "xfs.h" 7 #include "xfs_shared.h" 8 #include "xfs_format.h" 9 #include "xfs_log_format.h" 10 #include "xfs_trans_resv.h" 11 #include "xfs_mount.h" 12 #include "xfs_inode.h" 13 #include "xfs_attr.h" 14 #include "xfs_trace.h" 15 #include "xfs_error.h" 16 #include "xfs_acl.h" 17 #include "xfs_da_format.h" 18 #include "xfs_da_btree.h" 19 #include "xfs_trans.h" 20 21 #include <linux/posix_acl_xattr.h> 22 23 /* 24 * Locking scheme: 25 * - all ACL updates are protected by inode->i_mutex, which is taken before 26 * calling into this file. 27 */ 28 29 STATIC struct posix_acl * 30 xfs_acl_from_disk( 31 struct xfs_mount *mp, 32 const struct xfs_acl *aclp, 33 int len, 34 int max_entries) 35 { 36 struct posix_acl_entry *acl_e; 37 struct posix_acl *acl; 38 const struct xfs_acl_entry *ace; 39 unsigned int count, i; 40 41 if (len < sizeof(*aclp)) { 42 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, aclp, 43 len); 44 return ERR_PTR(-EFSCORRUPTED); 45 } 46 47 count = be32_to_cpu(aclp->acl_cnt); 48 if (count > max_entries || XFS_ACL_SIZE(count) != len) { 49 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, aclp, 50 len); 51 return ERR_PTR(-EFSCORRUPTED); 52 } 53 54 acl = posix_acl_alloc(count, GFP_KERNEL); 55 if (!acl) 56 return ERR_PTR(-ENOMEM); 57 58 for (i = 0; i < count; i++) { 59 acl_e = &acl->a_entries[i]; 60 ace = &aclp->acl_entry[i]; 61 62 /* 63 * The tag is 32 bits on disk and 16 bits in core. 64 * 65 * Because every access to it goes through the core 66 * format first this is not a problem. 67 */ 68 acl_e->e_tag = be32_to_cpu(ace->ae_tag); 69 acl_e->e_perm = be16_to_cpu(ace->ae_perm); 70 71 switch (acl_e->e_tag) { 72 case ACL_USER: 73 acl_e->e_uid = make_kuid(&init_user_ns, 74 be32_to_cpu(ace->ae_id)); 75 break; 76 case ACL_GROUP: 77 acl_e->e_gid = make_kgid(&init_user_ns, 78 be32_to_cpu(ace->ae_id)); 79 break; 80 case ACL_USER_OBJ: 81 case ACL_GROUP_OBJ: 82 case ACL_MASK: 83 case ACL_OTHER: 84 break; 85 default: 86 goto fail; 87 } 88 } 89 return acl; 90 91 fail: 92 posix_acl_release(acl); 93 return ERR_PTR(-EINVAL); 94 } 95 96 STATIC void 97 xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl) 98 { 99 const struct posix_acl_entry *acl_e; 100 struct xfs_acl_entry *ace; 101 int i; 102 103 aclp->acl_cnt = cpu_to_be32(acl->a_count); 104 for (i = 0; i < acl->a_count; i++) { 105 ace = &aclp->acl_entry[i]; 106 acl_e = &acl->a_entries[i]; 107 108 ace->ae_tag = cpu_to_be32(acl_e->e_tag); 109 switch (acl_e->e_tag) { 110 case ACL_USER: 111 ace->ae_id = cpu_to_be32( 112 from_kuid(&init_user_ns, acl_e->e_uid)); 113 break; 114 case ACL_GROUP: 115 ace->ae_id = cpu_to_be32( 116 from_kgid(&init_user_ns, acl_e->e_gid)); 117 break; 118 default: 119 ace->ae_id = cpu_to_be32(ACL_UNDEFINED_ID); 120 break; 121 } 122 123 ace->ae_perm = cpu_to_be16(acl_e->e_perm); 124 } 125 } 126 127 struct posix_acl * 128 xfs_get_acl(struct inode *inode, int type, bool rcu) 129 { 130 struct xfs_inode *ip = XFS_I(inode); 131 struct xfs_mount *mp = ip->i_mount; 132 struct posix_acl *acl = NULL; 133 struct xfs_da_args args = { 134 .dp = ip, 135 .attr_filter = XFS_ATTR_ROOT, 136 .valuelen = XFS_ACL_MAX_SIZE(mp), 137 }; 138 int error; 139 140 if (rcu) 141 return ERR_PTR(-ECHILD); 142 143 trace_xfs_get_acl(ip); 144 145 switch (type) { 146 case ACL_TYPE_ACCESS: 147 args.name = SGI_ACL_FILE; 148 break; 149 case ACL_TYPE_DEFAULT: 150 args.name = SGI_ACL_DEFAULT; 151 break; 152 default: 153 BUG(); 154 } 155 args.namelen = strlen(args.name); 156 157 /* 158 * If the attribute doesn't exist make sure we have a negative cache 159 * entry, for any other error assume it is transient. 160 */ 161 error = xfs_attr_get(&args); 162 if (!error) { 163 acl = xfs_acl_from_disk(mp, args.value, args.valuelen, 164 XFS_ACL_MAX_ENTRIES(mp)); 165 } else if (error != -ENOATTR) { 166 acl = ERR_PTR(error); 167 } 168 169 kmem_free(args.value); 170 return acl; 171 } 172 173 int 174 __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) 175 { 176 struct xfs_inode *ip = XFS_I(inode); 177 struct xfs_da_args args = { 178 .dp = ip, 179 .attr_filter = XFS_ATTR_ROOT, 180 }; 181 int error; 182 183 switch (type) { 184 case ACL_TYPE_ACCESS: 185 args.name = SGI_ACL_FILE; 186 break; 187 case ACL_TYPE_DEFAULT: 188 if (!S_ISDIR(inode->i_mode)) 189 return acl ? -EACCES : 0; 190 args.name = SGI_ACL_DEFAULT; 191 break; 192 default: 193 return -EINVAL; 194 } 195 args.namelen = strlen(args.name); 196 197 if (acl) { 198 args.valuelen = XFS_ACL_SIZE(acl->a_count); 199 args.value = kvzalloc(args.valuelen, GFP_KERNEL); 200 if (!args.value) 201 return -ENOMEM; 202 xfs_acl_to_disk(args.value, acl); 203 } 204 205 error = xfs_attr_set(&args); 206 kmem_free(args.value); 207 208 /* 209 * If the attribute didn't exist to start with that's fine. 210 */ 211 if (!acl && error == -ENOATTR) 212 error = 0; 213 if (!error) 214 set_cached_acl(inode, type, acl); 215 return error; 216 } 217 218 static int 219 xfs_acl_set_mode( 220 struct inode *inode, 221 umode_t mode) 222 { 223 struct xfs_inode *ip = XFS_I(inode); 224 struct xfs_mount *mp = ip->i_mount; 225 struct xfs_trans *tp; 226 int error; 227 228 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp); 229 if (error) 230 return error; 231 232 xfs_ilock(ip, XFS_ILOCK_EXCL); 233 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 234 inode->i_mode = mode; 235 inode->i_ctime = current_time(inode); 236 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 237 238 if (xfs_has_wsync(mp)) 239 xfs_trans_set_sync(tp); 240 return xfs_trans_commit(tp); 241 } 242 243 int 244 xfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, 245 struct posix_acl *acl, int type) 246 { 247 umode_t mode; 248 bool set_mode = false; 249 int error = 0; 250 251 if (!acl) 252 goto set_acl; 253 254 error = -E2BIG; 255 if (acl->a_count > XFS_ACL_MAX_ENTRIES(XFS_M(inode->i_sb))) 256 return error; 257 258 if (type == ACL_TYPE_ACCESS) { 259 error = posix_acl_update_mode(mnt_userns, inode, &mode, &acl); 260 if (error) 261 return error; 262 set_mode = true; 263 } 264 265 set_acl: 266 /* 267 * We set the mode after successfully updating the ACL xattr because the 268 * xattr update can fail at ENOSPC and we don't want to change the mode 269 * if the ACL update hasn't been applied. 270 */ 271 error = __xfs_set_acl(inode, acl, type); 272 if (!error && set_mode && mode != inode->i_mode) 273 error = xfs_acl_set_mode(inode, mode); 274 return error; 275 } 276 277 /* 278 * Invalidate any cached ACLs if the user has bypassed the ACL interface. 279 * We don't validate the content whatsoever so it is caller responsibility to 280 * provide data in valid format and ensure i_mode is consistent. 281 */ 282 void 283 xfs_forget_acl( 284 struct inode *inode, 285 const char *name) 286 { 287 if (!strcmp(name, SGI_ACL_FILE)) 288 forget_cached_acl(inode, ACL_TYPE_ACCESS); 289 else if (!strcmp(name, SGI_ACL_DEFAULT)) 290 forget_cached_acl(inode, ACL_TYPE_DEFAULT); 291 } 292