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) 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 trace_xfs_get_acl(ip); 141 142 switch (type) { 143 case ACL_TYPE_ACCESS: 144 args.name = SGI_ACL_FILE; 145 break; 146 case ACL_TYPE_DEFAULT: 147 args.name = SGI_ACL_DEFAULT; 148 break; 149 default: 150 BUG(); 151 } 152 args.namelen = strlen(args.name); 153 154 /* 155 * If the attribute doesn't exist make sure we have a negative cache 156 * entry, for any other error assume it is transient. 157 */ 158 error = xfs_attr_get(&args); 159 if (!error) { 160 acl = xfs_acl_from_disk(mp, args.value, args.valuelen, 161 XFS_ACL_MAX_ENTRIES(mp)); 162 } else if (error != -ENOATTR) { 163 acl = ERR_PTR(error); 164 } 165 166 kmem_free(args.value); 167 return acl; 168 } 169 170 int 171 __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) 172 { 173 struct xfs_inode *ip = XFS_I(inode); 174 struct xfs_da_args args = { 175 .dp = ip, 176 .attr_filter = XFS_ATTR_ROOT, 177 }; 178 int error; 179 180 switch (type) { 181 case ACL_TYPE_ACCESS: 182 args.name = SGI_ACL_FILE; 183 break; 184 case ACL_TYPE_DEFAULT: 185 if (!S_ISDIR(inode->i_mode)) 186 return acl ? -EACCES : 0; 187 args.name = SGI_ACL_DEFAULT; 188 break; 189 default: 190 return -EINVAL; 191 } 192 args.namelen = strlen(args.name); 193 194 if (acl) { 195 args.valuelen = XFS_ACL_SIZE(acl->a_count); 196 args.value = kvzalloc(args.valuelen, GFP_KERNEL); 197 if (!args.value) 198 return -ENOMEM; 199 xfs_acl_to_disk(args.value, acl); 200 } 201 202 error = xfs_attr_set(&args); 203 kmem_free(args.value); 204 205 /* 206 * If the attribute didn't exist to start with that's fine. 207 */ 208 if (!acl && error == -ENOATTR) 209 error = 0; 210 if (!error) 211 set_cached_acl(inode, type, acl); 212 return error; 213 } 214 215 static int 216 xfs_acl_set_mode( 217 struct inode *inode, 218 umode_t mode) 219 { 220 struct xfs_inode *ip = XFS_I(inode); 221 struct xfs_mount *mp = ip->i_mount; 222 struct xfs_trans *tp; 223 int error; 224 225 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp); 226 if (error) 227 return error; 228 229 xfs_ilock(ip, XFS_ILOCK_EXCL); 230 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 231 inode->i_mode = mode; 232 inode->i_ctime = current_time(inode); 233 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 234 235 if (mp->m_flags & XFS_MOUNT_WSYNC) 236 xfs_trans_set_sync(tp); 237 return xfs_trans_commit(tp); 238 } 239 240 int 241 xfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, 242 struct posix_acl *acl, int type) 243 { 244 umode_t mode; 245 bool set_mode = false; 246 int error = 0; 247 248 if (!acl) 249 goto set_acl; 250 251 error = -E2BIG; 252 if (acl->a_count > XFS_ACL_MAX_ENTRIES(XFS_M(inode->i_sb))) 253 return error; 254 255 if (type == ACL_TYPE_ACCESS) { 256 error = posix_acl_update_mode(mnt_userns, inode, &mode, &acl); 257 if (error) 258 return error; 259 set_mode = true; 260 } 261 262 set_acl: 263 /* 264 * We set the mode after successfully updating the ACL xattr because the 265 * xattr update can fail at ENOSPC and we don't want to change the mode 266 * if the ACL update hasn't been applied. 267 */ 268 error = __xfs_set_acl(inode, acl, type); 269 if (!error && set_mode && mode != inode->i_mode) 270 error = xfs_acl_set_mode(inode, mode); 271 return error; 272 } 273 274 /* 275 * Invalidate any cached ACLs if the user has bypassed the ACL interface. 276 * We don't validate the content whatsoever so it is caller responsibility to 277 * provide data in valid format and ensure i_mode is consistent. 278 */ 279 void 280 xfs_forget_acl( 281 struct inode *inode, 282 const char *name) 283 { 284 if (!strcmp(name, SGI_ACL_FILE)) 285 forget_cached_acl(inode, ACL_TYPE_ACCESS); 286 else if (!strcmp(name, SGI_ACL_DEFAULT)) 287 forget_cached_acl(inode, ACL_TYPE_DEFAULT); 288 } 289