xfs_acl.c 6.3 KB

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