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		goto no_mem;
568
569	ret = posix_acl_create_masq(*acl, mode);
570	if (ret < 0)
571		goto no_mem_clone;
572
573	if (ret == 0) {
574		posix_acl_release(*acl);
575		*acl = NULL;
576	}
577
578	if (!S_ISDIR(*mode)) {
579		posix_acl_release(p);
580		*default_acl = NULL;
581	} else {
582		*default_acl = p;
583	}
584	return 0;
585
586apply_umask:
587	*mode &= ~current_umask();
588no_acl:
589	*default_acl = NULL;
590	*acl = NULL;
591	return 0;
592
593no_mem_clone:
594	posix_acl_release(*acl);
595no_mem:
596	posix_acl_release(p);
597	return -ENOMEM;
598}
599EXPORT_SYMBOL_GPL(posix_acl_create);
600
601/*
602 * Fix up the uids and gids in posix acl extended attributes in place.
603 */
604static void posix_acl_fix_xattr_userns(
605	struct user_namespace *to, struct user_namespace *from,
606	void *value, size_t size)
607{
608	posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
609	posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
610	int count;
611	kuid_t uid;
612	kgid_t gid;
613
614	if (!value)
615		return;
616	if (size < sizeof(posix_acl_xattr_header))
617		return;
618	if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
619		return;
620
621	count = posix_acl_xattr_count(size);
622	if (count < 0)
623		return;
624	if (count == 0)
625		return;
626
627	for (end = entry + count; entry != end; entry++) {
628		switch(le16_to_cpu(entry->e_tag)) {
629		case ACL_USER:
630			uid = make_kuid(from, le32_to_cpu(entry->e_id));
631			entry->e_id = cpu_to_le32(from_kuid(to, uid));
632			break;
633		case ACL_GROUP:
634			gid = make_kgid(from, le32_to_cpu(entry->e_id));
635			entry->e_id = cpu_to_le32(from_kgid(to, gid));
636			break;
637		default:
638			break;
639		}
640	}
641}
642
643void posix_acl_fix_xattr_from_user(void *value, size_t size)
644{
645	struct user_namespace *user_ns = current_user_ns();
646	if (user_ns == &init_user_ns)
647		return;
648	posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size);
649}
650
651void posix_acl_fix_xattr_to_user(void *value, size_t size)
652{
653	struct user_namespace *user_ns = current_user_ns();
654	if (user_ns == &init_user_ns)
655		return;
656	posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size);
657}
658
659/*
660 * Convert from extended attribute to in-memory representation.
661 */
662struct posix_acl *
663posix_acl_from_xattr(struct user_namespace *user_ns,
664		     const void *value, size_t size)
665{
666	posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
667	posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
668	int count;
669	struct posix_acl *acl;
670	struct posix_acl_entry *acl_e;
671
672	if (!value)
673		return NULL;
674	if (size < sizeof(posix_acl_xattr_header))
675		 return ERR_PTR(-EINVAL);
676	if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
677		return ERR_PTR(-EOPNOTSUPP);
678
679	count = posix_acl_xattr_count(size);
680	if (count < 0)
681		return ERR_PTR(-EINVAL);
682	if (count == 0)
683		return NULL;
684
685	acl = posix_acl_alloc(count, GFP_NOFS);
686	if (!acl)
687		return ERR_PTR(-ENOMEM);
688	acl_e = acl->a_entries;
689
690	for (end = entry + count; entry != end; acl_e++, entry++) {
691		acl_e->e_tag  = le16_to_cpu(entry->e_tag);
692		acl_e->e_perm = le16_to_cpu(entry->e_perm);
693
694		switch(acl_e->e_tag) {
695			case ACL_USER_OBJ:
696			case ACL_GROUP_OBJ:
697			case ACL_MASK:
698			case ACL_OTHER:
699				break;
700
701			case ACL_USER:
702				acl_e->e_uid =
703					make_kuid(user_ns,
704						  le32_to_cpu(entry->e_id));
705				if (!uid_valid(acl_e->e_uid))
706					goto fail;
707				break;
708			case ACL_GROUP:
709				acl_e->e_gid =
710					make_kgid(user_ns,
711						  le32_to_cpu(entry->e_id));
712				if (!gid_valid(acl_e->e_gid))
713					goto fail;
714				break;
715
716			default:
717				goto fail;
718		}
719	}
720	return acl;
721
722fail:
723	posix_acl_release(acl);
724	return ERR_PTR(-EINVAL);
725}
726EXPORT_SYMBOL (posix_acl_from_xattr);
727
728/*
729 * Convert from in-memory to extended attribute representation.
730 */
731int
732posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
733		   void *buffer, size_t size)
734{
735	posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer;
736	posix_acl_xattr_entry *ext_entry;
737	int real_size, n;
738
739	real_size = posix_acl_xattr_size(acl->a_count);
740	if (!buffer)
741		return real_size;
742	if (real_size > size)
743		return -ERANGE;
744
745	ext_entry = ext_acl->a_entries;
746	ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
747
748	for (n=0; n < acl->a_count; n++, ext_entry++) {
749		const struct posix_acl_entry *acl_e = &acl->a_entries[n];
750		ext_entry->e_tag  = cpu_to_le16(acl_e->e_tag);
751		ext_entry->e_perm = cpu_to_le16(acl_e->e_perm);
752		switch(acl_e->e_tag) {
753		case ACL_USER:
754			ext_entry->e_id =
755				cpu_to_le32(from_kuid(user_ns, acl_e->e_uid));
756			break;
757		case ACL_GROUP:
758			ext_entry->e_id =
759				cpu_to_le32(from_kgid(user_ns, acl_e->e_gid));
760			break;
761		default:
762			ext_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
763			break;
764		}
765	}
766	return real_size;
767}
768EXPORT_SYMBOL (posix_acl_to_xattr);
769
770static int
771posix_acl_xattr_get(struct dentry *dentry, const char *name,
772		void *value, size_t size, int type)
773{
774	struct posix_acl *acl;
775	int error;
776
777	if (!IS_POSIXACL(d_backing_inode(dentry)))
778		return -EOPNOTSUPP;
779	if (d_is_symlink(dentry))
780		return -EOPNOTSUPP;
781
782	acl = get_acl(d_backing_inode(dentry), type);
783	if (IS_ERR(acl))
784		return PTR_ERR(acl);
785	if (acl == NULL)
786		return -ENODATA;
787
788	error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
789	posix_acl_release(acl);
790
791	return error;
792}
793
794static int
795posix_acl_xattr_set(struct dentry *dentry, const char *name,
796		const void *value, size_t size, int flags, int type)
797{
798	struct inode *inode = d_backing_inode(dentry);
799	struct posix_acl *acl = NULL;
800	int ret;
801
802	if (!IS_POSIXACL(inode))
803		return -EOPNOTSUPP;
804	if (!inode->i_op->set_acl)
805		return -EOPNOTSUPP;
806
807	if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
808		return value ? -EACCES : 0;
809	if (!inode_owner_or_capable(inode))
810		return -EPERM;
811
812	if (value) {
813		acl = posix_acl_from_xattr(&init_user_ns, value, size);
814		if (IS_ERR(acl))
815			return PTR_ERR(acl);
816
817		if (acl) {
818			ret = posix_acl_valid(acl);
819			if (ret)
820				goto out;
821		}
822	}
823
824	ret = inode->i_op->set_acl(inode, acl, type);
825out:
826	posix_acl_release(acl);
827	return ret;
828}
829
830static size_t
831posix_acl_xattr_list(struct dentry *dentry, char *list, size_t list_size,
832		const char *name, size_t name_len, int type)
833{
834	const char *xname;
835	size_t size;
836
837	if (!IS_POSIXACL(d_backing_inode(dentry)))
838		return -EOPNOTSUPP;
839	if (d_is_symlink(dentry))
840		return -EOPNOTSUPP;
841
842	if (type == ACL_TYPE_ACCESS)
843		xname = POSIX_ACL_XATTR_ACCESS;
844	else
845		xname = POSIX_ACL_XATTR_DEFAULT;
846
847	size = strlen(xname) + 1;
848	if (list && size <= list_size)
849		memcpy(list, xname, size);
850	return size;
851}
852
853const struct xattr_handler posix_acl_access_xattr_handler = {
854	.prefix = POSIX_ACL_XATTR_ACCESS,
855	.flags = ACL_TYPE_ACCESS,
856	.list = posix_acl_xattr_list,
857	.get = posix_acl_xattr_get,
858	.set = posix_acl_xattr_set,
859};
860EXPORT_SYMBOL_GPL(posix_acl_access_xattr_handler);
861
862const struct xattr_handler posix_acl_default_xattr_handler = {
863	.prefix = POSIX_ACL_XATTR_DEFAULT,
864	.flags = ACL_TYPE_DEFAULT,
865	.list = posix_acl_xattr_list,
866	.get = posix_acl_xattr_get,
867	.set = posix_acl_xattr_set,
868};
869EXPORT_SYMBOL_GPL(posix_acl_default_xattr_handler);
870
871int simple_set_acl(struct inode *inode, struct posix_acl *acl, int type)
872{
873	int error;
874
875	if (type == ACL_TYPE_ACCESS) {
876		error = posix_acl_equiv_mode(acl, &inode->i_mode);
877		if (error < 0)
878			return 0;
879		if (error == 0)
880			acl = NULL;
881	}
882
883	inode->i_ctime = CURRENT_TIME;
884	set_cached_acl(inode, type, acl);
885	return 0;
886}
887
888int simple_acl_create(struct inode *dir, struct inode *inode)
889{
890	struct posix_acl *default_acl, *acl;
891	int error;
892
893	error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
894	if (error)
895		return error;
896
897	set_cached_acl(inode, ACL_TYPE_DEFAULT, default_acl);
898	set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
899
900	if (default_acl)
901		posix_acl_release(default_acl);
902	if (acl)
903		posix_acl_release(acl);
904	return 0;
905}
906