1 /* 2 * Copyright (C) 2002,2003 by Andreas Gruenbacher <a.gruenbacher@computer.org> 3 * 4 * Fixes from William Schumacher incorporated on 15 March 2001. 5 * (Reported by Charles Bertsch, <CBertsch@microtest.com>). 6 */ 7 8 /* 9 * This file contains generic functions for manipulating 10 * POSIX 1003.1e draft standard 17 ACLs. 11 */ 12 13 #include <linux/kernel.h> 14 #include <linux/slab.h> 15 #include <linux/atomic.h> 16 #include <linux/fs.h> 17 #include <linux/sched.h> 18 #include <linux/cred.h> 19 #include <linux/posix_acl.h> 20 #include <linux/posix_acl_xattr.h> 21 #include <linux/xattr.h> 22 #include <linux/export.h> 23 #include <linux/user_namespace.h> 24 25 static struct posix_acl **acl_by_type(struct inode *inode, int type) 26 { 27 switch (type) { 28 case ACL_TYPE_ACCESS: 29 return &inode->i_acl; 30 case ACL_TYPE_DEFAULT: 31 return &inode->i_default_acl; 32 default: 33 BUG(); 34 } 35 } 36 37 struct posix_acl *get_cached_acl(struct inode *inode, int type) 38 { 39 struct posix_acl **p = acl_by_type(inode, type); 40 struct posix_acl *acl; 41 42 for (;;) { 43 rcu_read_lock(); 44 acl = rcu_dereference(*p); 45 if (!acl || is_uncached_acl(acl) || 46 atomic_inc_not_zero(&acl->a_refcount)) 47 break; 48 rcu_read_unlock(); 49 cpu_relax(); 50 } 51 rcu_read_unlock(); 52 return acl; 53 } 54 EXPORT_SYMBOL(get_cached_acl); 55 56 struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type) 57 { 58 return rcu_dereference(*acl_by_type(inode, type)); 59 } 60 EXPORT_SYMBOL(get_cached_acl_rcu); 61 62 void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl) 63 { 64 struct posix_acl **p = acl_by_type(inode, type); 65 struct posix_acl *old; 66 67 old = xchg(p, posix_acl_dup(acl)); 68 if (!is_uncached_acl(old)) 69 posix_acl_release(old); 70 } 71 EXPORT_SYMBOL(set_cached_acl); 72 73 static void __forget_cached_acl(struct posix_acl **p) 74 { 75 struct posix_acl *old; 76 77 old = xchg(p, ACL_NOT_CACHED); 78 if (!is_uncached_acl(old)) 79 posix_acl_release(old); 80 } 81 82 void forget_cached_acl(struct inode *inode, int type) 83 { 84 __forget_cached_acl(acl_by_type(inode, type)); 85 } 86 EXPORT_SYMBOL(forget_cached_acl); 87 88 void forget_all_cached_acls(struct inode *inode) 89 { 90 __forget_cached_acl(&inode->i_acl); 91 __forget_cached_acl(&inode->i_default_acl); 92 } 93 EXPORT_SYMBOL(forget_all_cached_acls); 94 95 struct posix_acl *get_acl(struct inode *inode, int type) 96 { 97 void *sentinel; 98 struct posix_acl **p; 99 struct posix_acl *acl; 100 101 /* 102 * The sentinel is used to detect when another operation like 103 * set_cached_acl() or forget_cached_acl() races with get_acl(). 104 * It is guaranteed that is_uncached_acl(sentinel) is true. 105 */ 106 107 acl = get_cached_acl(inode, type); 108 if (!is_uncached_acl(acl)) 109 return acl; 110 111 if (!IS_POSIXACL(inode)) 112 return NULL; 113 114 sentinel = uncached_acl_sentinel(current); 115 p = acl_by_type(inode, type); 116 117 /* 118 * If the ACL isn't being read yet, set our sentinel. Otherwise, the 119 * current value of the ACL will not be ACL_NOT_CACHED and so our own 120 * sentinel will not be set; another task will update the cache. We 121 * could wait for that other task to complete its job, but it's easier 122 * to just call ->get_acl to fetch the ACL ourself. (This is going to 123 * be an unlikely race.) 124 */ 125 if (cmpxchg(p, ACL_NOT_CACHED, sentinel) != ACL_NOT_CACHED) 126 /* fall through */ ; 127 128 /* 129 * Normally, the ACL returned by ->get_acl will be cached. 130 * A filesystem can prevent that by calling 131 * forget_cached_acl(inode, type) in ->get_acl. 132 * 133 * If the filesystem doesn't have a get_acl() function at all, we'll 134 * just create the negative cache entry. 135 */ 136 if (!inode->i_op->get_acl) { 137 set_cached_acl(inode, type, NULL); 138 return NULL; 139 } 140 acl = inode->i_op->get_acl(inode, type); 141 142 if (IS_ERR(acl)) { 143 /* 144 * Remove our sentinel so that we don't block future attempts 145 * to cache the ACL. 146 */ 147 cmpxchg(p, sentinel, ACL_NOT_CACHED); 148 return acl; 149 } 150 151 /* 152 * Cache the result, but only if our sentinel is still in place. 153 */ 154 posix_acl_dup(acl); 155 if (unlikely(cmpxchg(p, sentinel, acl) != sentinel)) 156 posix_acl_release(acl); 157 return acl; 158 } 159 EXPORT_SYMBOL(get_acl); 160 161 /* 162 * Init a fresh posix_acl 163 */ 164 void 165 posix_acl_init(struct posix_acl *acl, int count) 166 { 167 atomic_set(&acl->a_refcount, 1); 168 acl->a_count = count; 169 } 170 EXPORT_SYMBOL(posix_acl_init); 171 172 /* 173 * Allocate a new ACL with the specified number of entries. 174 */ 175 struct posix_acl * 176 posix_acl_alloc(int count, gfp_t flags) 177 { 178 const size_t size = sizeof(struct posix_acl) + 179 count * sizeof(struct posix_acl_entry); 180 struct posix_acl *acl = kmalloc(size, flags); 181 if (acl) 182 posix_acl_init(acl, count); 183 return acl; 184 } 185 EXPORT_SYMBOL(posix_acl_alloc); 186 187 /* 188 * Clone an ACL. 189 */ 190 static struct posix_acl * 191 posix_acl_clone(const struct posix_acl *acl, gfp_t flags) 192 { 193 struct posix_acl *clone = NULL; 194 195 if (acl) { 196 int size = sizeof(struct posix_acl) + acl->a_count * 197 sizeof(struct posix_acl_entry); 198 clone = kmemdup(acl, size, flags); 199 if (clone) 200 atomic_set(&clone->a_refcount, 1); 201 } 202 return clone; 203 } 204 205 /* 206 * Check if an acl is valid. Returns 0 if it is, or -E... otherwise. 207 */ 208 int 209 posix_acl_valid(struct user_namespace *user_ns, const struct posix_acl *acl) 210 { 211 const struct posix_acl_entry *pa, *pe; 212 int state = ACL_USER_OBJ; 213 int needs_mask = 0; 214 215 FOREACH_ACL_ENTRY(pa, acl, pe) { 216 if (pa->e_perm & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE)) 217 return -EINVAL; 218 switch (pa->e_tag) { 219 case ACL_USER_OBJ: 220 if (state == ACL_USER_OBJ) { 221 state = ACL_USER; 222 break; 223 } 224 return -EINVAL; 225 226 case ACL_USER: 227 if (state != ACL_USER) 228 return -EINVAL; 229 if (!kuid_has_mapping(user_ns, pa->e_uid)) 230 return -EINVAL; 231 needs_mask = 1; 232 break; 233 234 case ACL_GROUP_OBJ: 235 if (state == ACL_USER) { 236 state = ACL_GROUP; 237 break; 238 } 239 return -EINVAL; 240 241 case ACL_GROUP: 242 if (state != ACL_GROUP) 243 return -EINVAL; 244 if (!kgid_has_mapping(user_ns, pa->e_gid)) 245 return -EINVAL; 246 needs_mask = 1; 247 break; 248 249 case ACL_MASK: 250 if (state != ACL_GROUP) 251 return -EINVAL; 252 state = ACL_OTHER; 253 break; 254 255 case ACL_OTHER: 256 if (state == ACL_OTHER || 257 (state == ACL_GROUP && !needs_mask)) { 258 state = 0; 259 break; 260 } 261 return -EINVAL; 262 263 default: 264 return -EINVAL; 265 } 266 } 267 if (state == 0) 268 return 0; 269 return -EINVAL; 270 } 271 EXPORT_SYMBOL(posix_acl_valid); 272 273 /* 274 * Returns 0 if the acl can be exactly represented in the traditional 275 * file mode permission bits, or else 1. Returns -E... on error. 276 */ 277 int 278 posix_acl_equiv_mode(const struct posix_acl *acl, umode_t *mode_p) 279 { 280 const struct posix_acl_entry *pa, *pe; 281 umode_t mode = 0; 282 int not_equiv = 0; 283 284 /* 285 * A null ACL can always be presented as mode bits. 286 */ 287 if (!acl) 288 return 0; 289 290 FOREACH_ACL_ENTRY(pa, acl, pe) { 291 switch (pa->e_tag) { 292 case ACL_USER_OBJ: 293 mode |= (pa->e_perm & S_IRWXO) << 6; 294 break; 295 case ACL_GROUP_OBJ: 296 mode |= (pa->e_perm & S_IRWXO) << 3; 297 break; 298 case ACL_OTHER: 299 mode |= pa->e_perm & S_IRWXO; 300 break; 301 case ACL_MASK: 302 mode = (mode & ~S_IRWXG) | 303 ((pa->e_perm & S_IRWXO) << 3); 304 not_equiv = 1; 305 break; 306 case ACL_USER: 307 case ACL_GROUP: 308 not_equiv = 1; 309 break; 310 default: 311 return -EINVAL; 312 } 313 } 314 if (mode_p) 315 *mode_p = (*mode_p & ~S_IRWXUGO) | mode; 316 return not_equiv; 317 } 318 EXPORT_SYMBOL(posix_acl_equiv_mode); 319 320 /* 321 * Create an ACL representing the file mode permission bits of an inode. 322 */ 323 struct posix_acl * 324 posix_acl_from_mode(umode_t mode, gfp_t flags) 325 { 326 struct posix_acl *acl = posix_acl_alloc(3, flags); 327 if (!acl) 328 return ERR_PTR(-ENOMEM); 329 330 acl->a_entries[0].e_tag = ACL_USER_OBJ; 331 acl->a_entries[0].e_perm = (mode & S_IRWXU) >> 6; 332 333 acl->a_entries[1].e_tag = ACL_GROUP_OBJ; 334 acl->a_entries[1].e_perm = (mode & S_IRWXG) >> 3; 335 336 acl->a_entries[2].e_tag = ACL_OTHER; 337 acl->a_entries[2].e_perm = (mode & S_IRWXO); 338 return acl; 339 } 340 EXPORT_SYMBOL(posix_acl_from_mode); 341 342 /* 343 * Return 0 if current is granted want access to the inode 344 * by the acl. Returns -E... otherwise. 345 */ 346 int 347 posix_acl_permission(struct inode *inode, const struct posix_acl *acl, int want) 348 { 349 const struct posix_acl_entry *pa, *pe, *mask_obj; 350 int found = 0; 351 352 want &= MAY_READ | MAY_WRITE | MAY_EXEC | MAY_NOT_BLOCK; 353 354 FOREACH_ACL_ENTRY(pa, acl, pe) { 355 switch(pa->e_tag) { 356 case ACL_USER_OBJ: 357 /* (May have been checked already) */ 358 if (uid_eq(inode->i_uid, current_fsuid())) 359 goto check_perm; 360 break; 361 case ACL_USER: 362 if (uid_eq(pa->e_uid, current_fsuid())) 363 goto mask; 364 break; 365 case ACL_GROUP_OBJ: 366 if (in_group_p(inode->i_gid)) { 367 found = 1; 368 if ((pa->e_perm & want) == want) 369 goto mask; 370 } 371 break; 372 case ACL_GROUP: 373 if (in_group_p(pa->e_gid)) { 374 found = 1; 375 if ((pa->e_perm & want) == want) 376 goto mask; 377 } 378 break; 379 case ACL_MASK: 380 break; 381 case ACL_OTHER: 382 if (found) 383 return -EACCES; 384 else 385 goto check_perm; 386 default: 387 return -EIO; 388 } 389 } 390 return -EIO; 391 392 mask: 393 for (mask_obj = pa+1; mask_obj != pe; mask_obj++) { 394 if (mask_obj->e_tag == ACL_MASK) { 395 if ((pa->e_perm & mask_obj->e_perm & want) == want) 396 return 0; 397 return -EACCES; 398 } 399 } 400 401 check_perm: 402 if ((pa->e_perm & want) == want) 403 return 0; 404 return -EACCES; 405 } 406 407 /* 408 * Modify acl when creating a new inode. The caller must ensure the acl is 409 * only referenced once. 410 * 411 * mode_p initially must contain the mode parameter to the open() / creat() 412 * system calls. All permissions that are not granted by the acl are removed. 413 * The permissions in the acl are changed to reflect the mode_p parameter. 414 */ 415 static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) 416 { 417 struct posix_acl_entry *pa, *pe; 418 struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; 419 umode_t mode = *mode_p; 420 int not_equiv = 0; 421 422 /* assert(atomic_read(acl->a_refcount) == 1); */ 423 424 FOREACH_ACL_ENTRY(pa, acl, pe) { 425 switch(pa->e_tag) { 426 case ACL_USER_OBJ: 427 pa->e_perm &= (mode >> 6) | ~S_IRWXO; 428 mode &= (pa->e_perm << 6) | ~S_IRWXU; 429 break; 430 431 case ACL_USER: 432 case ACL_GROUP: 433 not_equiv = 1; 434 break; 435 436 case ACL_GROUP_OBJ: 437 group_obj = pa; 438 break; 439 440 case ACL_OTHER: 441 pa->e_perm &= mode | ~S_IRWXO; 442 mode &= pa->e_perm | ~S_IRWXO; 443 break; 444 445 case ACL_MASK: 446 mask_obj = pa; 447 not_equiv = 1; 448 break; 449 450 default: 451 return -EIO; 452 } 453 } 454 455 if (mask_obj) { 456 mask_obj->e_perm &= (mode >> 3) | ~S_IRWXO; 457 mode &= (mask_obj->e_perm << 3) | ~S_IRWXG; 458 } else { 459 if (!group_obj) 460 return -EIO; 461 group_obj->e_perm &= (mode >> 3) | ~S_IRWXO; 462 mode &= (group_obj->e_perm << 3) | ~S_IRWXG; 463 } 464 465 *mode_p = (*mode_p & ~S_IRWXUGO) | mode; 466 return not_equiv; 467 } 468 469 /* 470 * Modify the ACL for the chmod syscall. 471 */ 472 static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode) 473 { 474 struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; 475 struct posix_acl_entry *pa, *pe; 476 477 /* assert(atomic_read(acl->a_refcount) == 1); */ 478 479 FOREACH_ACL_ENTRY(pa, acl, pe) { 480 switch(pa->e_tag) { 481 case ACL_USER_OBJ: 482 pa->e_perm = (mode & S_IRWXU) >> 6; 483 break; 484 485 case ACL_USER: 486 case ACL_GROUP: 487 break; 488 489 case ACL_GROUP_OBJ: 490 group_obj = pa; 491 break; 492 493 case ACL_MASK: 494 mask_obj = pa; 495 break; 496 497 case ACL_OTHER: 498 pa->e_perm = (mode & S_IRWXO); 499 break; 500 501 default: 502 return -EIO; 503 } 504 } 505 506 if (mask_obj) { 507 mask_obj->e_perm = (mode & S_IRWXG) >> 3; 508 } else { 509 if (!group_obj) 510 return -EIO; 511 group_obj->e_perm = (mode & S_IRWXG) >> 3; 512 } 513 514 return 0; 515 } 516 517 int 518 __posix_acl_create(struct posix_acl **acl, gfp_t gfp, umode_t *mode_p) 519 { 520 struct posix_acl *clone = posix_acl_clone(*acl, gfp); 521 int err = -ENOMEM; 522 if (clone) { 523 err = posix_acl_create_masq(clone, mode_p); 524 if (err < 0) { 525 posix_acl_release(clone); 526 clone = NULL; 527 } 528 } 529 posix_acl_release(*acl); 530 *acl = clone; 531 return err; 532 } 533 EXPORT_SYMBOL(__posix_acl_create); 534 535 int 536 __posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode) 537 { 538 struct posix_acl *clone = posix_acl_clone(*acl, gfp); 539 int err = -ENOMEM; 540 if (clone) { 541 err = __posix_acl_chmod_masq(clone, mode); 542 if (err) { 543 posix_acl_release(clone); 544 clone = NULL; 545 } 546 } 547 posix_acl_release(*acl); 548 *acl = clone; 549 return err; 550 } 551 EXPORT_SYMBOL(__posix_acl_chmod); 552 553 int 554 posix_acl_chmod(struct inode *inode, umode_t mode) 555 { 556 struct posix_acl *acl; 557 int ret = 0; 558 559 if (!IS_POSIXACL(inode)) 560 return 0; 561 if (!inode->i_op->set_acl) 562 return -EOPNOTSUPP; 563 564 acl = get_acl(inode, ACL_TYPE_ACCESS); 565 if (IS_ERR_OR_NULL(acl)) { 566 if (acl == ERR_PTR(-EOPNOTSUPP)) 567 return 0; 568 return PTR_ERR(acl); 569 } 570 571 ret = __posix_acl_chmod(&acl, GFP_KERNEL, mode); 572 if (ret) 573 return ret; 574 ret = inode->i_op->set_acl(inode, acl, ACL_TYPE_ACCESS); 575 posix_acl_release(acl); 576 return ret; 577 } 578 EXPORT_SYMBOL(posix_acl_chmod); 579 580 int 581 posix_acl_create(struct inode *dir, umode_t *mode, 582 struct posix_acl **default_acl, struct posix_acl **acl) 583 { 584 struct posix_acl *p; 585 struct posix_acl *clone; 586 int ret; 587 588 *acl = NULL; 589 *default_acl = NULL; 590 591 if (S_ISLNK(*mode) || !IS_POSIXACL(dir)) 592 return 0; 593 594 p = get_acl(dir, ACL_TYPE_DEFAULT); 595 if (!p || p == ERR_PTR(-EOPNOTSUPP)) { 596 *mode &= ~current_umask(); 597 return 0; 598 } 599 if (IS_ERR(p)) 600 return PTR_ERR(p); 601 602 ret = -ENOMEM; 603 clone = posix_acl_clone(p, GFP_NOFS); 604 if (!clone) 605 goto err_release; 606 607 ret = posix_acl_create_masq(clone, mode); 608 if (ret < 0) 609 goto err_release_clone; 610 611 if (ret == 0) 612 posix_acl_release(clone); 613 else 614 *acl = clone; 615 616 if (!S_ISDIR(*mode)) 617 posix_acl_release(p); 618 else 619 *default_acl = p; 620 621 return 0; 622 623 err_release_clone: 624 posix_acl_release(clone); 625 err_release: 626 posix_acl_release(p); 627 return ret; 628 } 629 EXPORT_SYMBOL_GPL(posix_acl_create); 630 631 /** 632 * posix_acl_update_mode - update mode in set_acl 633 * 634 * Update the file mode when setting an ACL: compute the new file permission 635 * bits based on the ACL. In addition, if the ACL is equivalent to the new 636 * file mode, set *acl to NULL to indicate that no ACL should be set. 637 * 638 * As with chmod, clear the setgit bit if the caller is not in the owning group 639 * or capable of CAP_FSETID (see inode_change_ok). 640 * 641 * Called from set_acl inode operations. 642 */ 643 int posix_acl_update_mode(struct inode *inode, umode_t *mode_p, 644 struct posix_acl **acl) 645 { 646 umode_t mode = inode->i_mode; 647 int error; 648 649 error = posix_acl_equiv_mode(*acl, &mode); 650 if (error < 0) 651 return error; 652 if (error == 0) 653 *acl = NULL; 654 if (!in_group_p(inode->i_gid) && 655 !capable_wrt_inode_uidgid(inode, CAP_FSETID)) 656 mode &= ~S_ISGID; 657 *mode_p = mode; 658 return 0; 659 } 660 EXPORT_SYMBOL(posix_acl_update_mode); 661 662 /* 663 * Fix up the uids and gids in posix acl extended attributes in place. 664 */ 665 static void posix_acl_fix_xattr_userns( 666 struct user_namespace *to, struct user_namespace *from, 667 void *value, size_t size) 668 { 669 struct posix_acl_xattr_header *header = value; 670 struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end; 671 int count; 672 kuid_t uid; 673 kgid_t gid; 674 675 if (!value) 676 return; 677 if (size < sizeof(struct posix_acl_xattr_header)) 678 return; 679 if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION)) 680 return; 681 682 count = posix_acl_xattr_count(size); 683 if (count < 0) 684 return; 685 if (count == 0) 686 return; 687 688 for (end = entry + count; entry != end; entry++) { 689 switch(le16_to_cpu(entry->e_tag)) { 690 case ACL_USER: 691 uid = make_kuid(from, le32_to_cpu(entry->e_id)); 692 entry->e_id = cpu_to_le32(from_kuid(to, uid)); 693 break; 694 case ACL_GROUP: 695 gid = make_kgid(from, le32_to_cpu(entry->e_id)); 696 entry->e_id = cpu_to_le32(from_kgid(to, gid)); 697 break; 698 default: 699 break; 700 } 701 } 702 } 703 704 void posix_acl_fix_xattr_from_user(void *value, size_t size) 705 { 706 struct user_namespace *user_ns = current_user_ns(); 707 if (user_ns == &init_user_ns) 708 return; 709 posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size); 710 } 711 712 void posix_acl_fix_xattr_to_user(void *value, size_t size) 713 { 714 struct user_namespace *user_ns = current_user_ns(); 715 if (user_ns == &init_user_ns) 716 return; 717 posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size); 718 } 719 720 /* 721 * Convert from extended attribute to in-memory representation. 722 */ 723 struct posix_acl * 724 posix_acl_from_xattr(struct user_namespace *user_ns, 725 const void *value, size_t size) 726 { 727 const struct posix_acl_xattr_header *header = value; 728 const struct posix_acl_xattr_entry *entry = (const void *)(header + 1), *end; 729 int count; 730 struct posix_acl *acl; 731 struct posix_acl_entry *acl_e; 732 733 if (!value) 734 return NULL; 735 if (size < sizeof(struct posix_acl_xattr_header)) 736 return ERR_PTR(-EINVAL); 737 if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION)) 738 return ERR_PTR(-EOPNOTSUPP); 739 740 count = posix_acl_xattr_count(size); 741 if (count < 0) 742 return ERR_PTR(-EINVAL); 743 if (count == 0) 744 return NULL; 745 746 acl = posix_acl_alloc(count, GFP_NOFS); 747 if (!acl) 748 return ERR_PTR(-ENOMEM); 749 acl_e = acl->a_entries; 750 751 for (end = entry + count; entry != end; acl_e++, entry++) { 752 acl_e->e_tag = le16_to_cpu(entry->e_tag); 753 acl_e->e_perm = le16_to_cpu(entry->e_perm); 754 755 switch(acl_e->e_tag) { 756 case ACL_USER_OBJ: 757 case ACL_GROUP_OBJ: 758 case ACL_MASK: 759 case ACL_OTHER: 760 break; 761 762 case ACL_USER: 763 acl_e->e_uid = 764 make_kuid(user_ns, 765 le32_to_cpu(entry->e_id)); 766 if (!uid_valid(acl_e->e_uid)) 767 goto fail; 768 break; 769 case ACL_GROUP: 770 acl_e->e_gid = 771 make_kgid(user_ns, 772 le32_to_cpu(entry->e_id)); 773 if (!gid_valid(acl_e->e_gid)) 774 goto fail; 775 break; 776 777 default: 778 goto fail; 779 } 780 } 781 return acl; 782 783 fail: 784 posix_acl_release(acl); 785 return ERR_PTR(-EINVAL); 786 } 787 EXPORT_SYMBOL (posix_acl_from_xattr); 788 789 /* 790 * Convert from in-memory to extended attribute representation. 791 */ 792 int 793 posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl, 794 void *buffer, size_t size) 795 { 796 struct posix_acl_xattr_header *ext_acl = buffer; 797 struct posix_acl_xattr_entry *ext_entry; 798 int real_size, n; 799 800 real_size = posix_acl_xattr_size(acl->a_count); 801 if (!buffer) 802 return real_size; 803 if (real_size > size) 804 return -ERANGE; 805 806 ext_entry = (void *)(ext_acl + 1); 807 ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION); 808 809 for (n=0; n < acl->a_count; n++, ext_entry++) { 810 const struct posix_acl_entry *acl_e = &acl->a_entries[n]; 811 ext_entry->e_tag = cpu_to_le16(acl_e->e_tag); 812 ext_entry->e_perm = cpu_to_le16(acl_e->e_perm); 813 switch(acl_e->e_tag) { 814 case ACL_USER: 815 ext_entry->e_id = 816 cpu_to_le32(from_kuid(user_ns, acl_e->e_uid)); 817 break; 818 case ACL_GROUP: 819 ext_entry->e_id = 820 cpu_to_le32(from_kgid(user_ns, acl_e->e_gid)); 821 break; 822 default: 823 ext_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID); 824 break; 825 } 826 } 827 return real_size; 828 } 829 EXPORT_SYMBOL (posix_acl_to_xattr); 830 831 static int 832 posix_acl_xattr_get(const struct xattr_handler *handler, 833 struct dentry *unused, struct inode *inode, 834 const char *name, void *value, size_t size) 835 { 836 struct posix_acl *acl; 837 int error; 838 839 if (!IS_POSIXACL(inode)) 840 return -EOPNOTSUPP; 841 if (S_ISLNK(inode->i_mode)) 842 return -EOPNOTSUPP; 843 844 acl = get_acl(inode, handler->flags); 845 if (IS_ERR(acl)) 846 return PTR_ERR(acl); 847 if (acl == NULL) 848 return -ENODATA; 849 850 error = posix_acl_to_xattr(&init_user_ns, acl, value, size); 851 posix_acl_release(acl); 852 853 return error; 854 } 855 856 int 857 set_posix_acl(struct inode *inode, int type, struct posix_acl *acl) 858 { 859 if (!IS_POSIXACL(inode)) 860 return -EOPNOTSUPP; 861 if (!inode->i_op->set_acl) 862 return -EOPNOTSUPP; 863 864 if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) 865 return acl ? -EACCES : 0; 866 if (!inode_owner_or_capable(inode)) 867 return -EPERM; 868 869 if (acl) { 870 int ret = posix_acl_valid(inode->i_sb->s_user_ns, acl); 871 if (ret) 872 return ret; 873 } 874 return inode->i_op->set_acl(inode, acl, type); 875 } 876 EXPORT_SYMBOL(set_posix_acl); 877 878 static int 879 posix_acl_xattr_set(const struct xattr_handler *handler, 880 struct dentry *unused, struct inode *inode, 881 const char *name, const void *value, 882 size_t size, int flags) 883 { 884 struct posix_acl *acl = NULL; 885 int ret; 886 887 if (value) { 888 acl = posix_acl_from_xattr(&init_user_ns, value, size); 889 if (IS_ERR(acl)) 890 return PTR_ERR(acl); 891 } 892 ret = set_posix_acl(inode, handler->flags, acl); 893 posix_acl_release(acl); 894 return ret; 895 } 896 897 static bool 898 posix_acl_xattr_list(struct dentry *dentry) 899 { 900 return IS_POSIXACL(d_backing_inode(dentry)); 901 } 902 903 const struct xattr_handler posix_acl_access_xattr_handler = { 904 .name = XATTR_NAME_POSIX_ACL_ACCESS, 905 .flags = ACL_TYPE_ACCESS, 906 .list = posix_acl_xattr_list, 907 .get = posix_acl_xattr_get, 908 .set = posix_acl_xattr_set, 909 }; 910 EXPORT_SYMBOL_GPL(posix_acl_access_xattr_handler); 911 912 const struct xattr_handler posix_acl_default_xattr_handler = { 913 .name = XATTR_NAME_POSIX_ACL_DEFAULT, 914 .flags = ACL_TYPE_DEFAULT, 915 .list = posix_acl_xattr_list, 916 .get = posix_acl_xattr_get, 917 .set = posix_acl_xattr_set, 918 }; 919 EXPORT_SYMBOL_GPL(posix_acl_default_xattr_handler); 920 921 int simple_set_acl(struct inode *inode, struct posix_acl *acl, int type) 922 { 923 int error; 924 925 if (type == ACL_TYPE_ACCESS) { 926 error = posix_acl_update_mode(inode, 927 &inode->i_mode, &acl); 928 if (error) 929 return error; 930 } 931 932 inode->i_ctime = current_time(inode); 933 set_cached_acl(inode, type, acl); 934 return 0; 935 } 936 937 int simple_acl_create(struct inode *dir, struct inode *inode) 938 { 939 struct posix_acl *default_acl, *acl; 940 int error; 941 942 error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl); 943 if (error) 944 return error; 945 946 set_cached_acl(inode, ACL_TYPE_DEFAULT, default_acl); 947 set_cached_acl(inode, ACL_TYPE_ACCESS, acl); 948 949 if (default_acl) 950 posix_acl_release(default_acl); 951 if (acl) 952 posix_acl_release(acl); 953 return 0; 954 } 955