Linux Audio

Check our new training course

Linux BSP development engineering services

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